Hlavní navigace

Hardening webového serveru Apache: šifrování a certifikáty

Pojem „hardening“ lze do českého jazyka přeložit jako „zodolnění“, „vyztužení“ nebo „zesílení“. Dnes si ukážeme, jak nastavit populární webový server Apache tak, aby splňoval moderní bezpečnostní standardy.
Michal Vymazal 10. 2. 2020
Doba čtení: 9 minut

Sdílet

V podstatě se jedná o sadu vylepšení nebo „zodolnění“ buď celého operačního systému, jeho konkrétní části, nebo určité aplikace. Vtip je ovšem v tom, že neměníme zdrojový kód, ale parametry konfigurace. Výsledkem může být kýžené „zodolnění“ systému nebo aplikace před nenechavci nebo určitými typy útoků. Na druhou stranu si ale také můžeme řádně zkomplikovat život. To když autoři aplikací (nebo protokolů) nerespektují standardy. Například administrátoři rozšíření mod_security by mohli vyprávět opravdu nehezké příběhy o tom, jak se nemají psát webové aplikace.

Na aplikační firewall mod_security se podíváme v jednom z příštích dílů seriálu, v tomto dílu se budu zabývat úpravou konfigurace www démona apache pro šifrovaný provoz.

Apache: pravidla pro šifrovaný provoz

Možná se budete divit, ale v nastavení www démonů je pořád co zlepšovat. Pro účely našeho seriálu jsem zvolil démona Apache, nastavení ostatních démonů (tomcat, nginx) bude principiálně stejné. Doporučená pravidla pro šifrování najdeme v dokumentu BSI Technical Guideline TR-02102–2. Německou národní bezpečnostní autoritu snad představovat nemusím, v dokumentu se dočteme zhruba toto:

Při konfiguraci SSL na straně serveru nezapomeňte zakázat protokoly SSL V2, V3 a TLS v1.0. Jinak budou uživatelská jména a hesla přenášena ve formátu prostého textu. TLS 1.1 pro změnu využívá SHA-1 a to rovněž není dobrá volba. Raději povolte pouze TLS verzi 1.2.

Ještě to bude chtít povolit pouze doporučené šifrovací mechanismy:



Poznámka: Všechny změny v konfiguraci provádějte jako root. Je celkem logické, že starší www prohlížeče (nepodporující vynucenou verzi TLS, nebo vynucené mechanismy šifrování) se po hardeningu k vašemu www serveru nepřipojí, ale to je daň společenského pokroku.

Změny v konfiguraci

Vlastní konfiguraci pak provádíme v konfiguračním souboru /etc/apache2/mods-available/ssl.conf, kde zápis požadovaných parametrů může vypadat takto:

# Enable TLSv1.2, disable SSLv3.0, TLSv1.0 and TLSv1.1
SSLProtocol             -all +TLSv1.2

# Po zavedeni podpory pro TLSv1.3 povolte TLSv1.3
# na vyse zakomentovanem radku s parametrem SSLProtocol

# Enable modern TLS cipher suites
SSLCipherSuite          ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256

# The order of cipher suites matters
SSLHonorCipherOrder     on

# Disable TLS compression
SSLCompression          off

# Necessary for Perfect Forward Secrecy (PFS)
SSLSessionTickets       off

V konfiguračním souboru vlastního virtuálního stroje ( /etc/apache2/sites-available/xxx-site.cz.conf) povolte toto:

##Permanent redirect to https
Redirect permanent / https://xxx-site.cz/
</VirtualHost>
<VirtualHost *:443>
ServerName xxx-site.cz
DocumentRoot "/var/www/html/xxx-site"
SSLEngine on

#Umístění privátního klíče a certifikátu
SSLCertificateFile      /etc/ssl/certs/example.com.crt
SSLCertificateKeyFile   /etc/ssl/private/example.com.key

#Nastavení HSTS
Header always add Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"

Poznámka: HTTP Strict Transport Security (HSTS) je bezpečnostní mechanismus, který chrání síťovou komunikaci mezi webovým prohlížečem a webovým serverem před downgrade útoky a zjednodušuje ochranu proti únosu spojení (tzv. cookie hijacking). Mechanismus umožňuje, aby webový server vynutil v prohlížeči komunikaci pouze pomocí šifrovaného HTTPS připojení a vyloučil tím přenos dat nezabezpečeným HTTP protokolem. HSTS definuje RFC 6797. Webový server aktivuje HSTS pomocí HTTP hlavičky Strict-Transport-Security, která svou hodnotou definuje časový úsek, po který může prohlížeč přistupovat k serveru výhradně zabezpečeně.

Potřebné moduly

Povolené moduly zjistíme tímto příkazem:

# sudo apachectl -M

Budeme potřebovat tyto moduly:

  • mod_ssl
  • mod_headers
  • mod_rewrite

Kontrola nastavení SSL/TLS – nástroje, ukázky výstupů

sslscan

Velmi užitečný skript, který je k dostání prakticky ve všech linuxových distribucích. Potíž je ovšem v tom, že některé distribuční balíčky mají problémy s TLSv1.1 a TLSv1.2, takže s balíčky z těchto distribucí (např. Ubuntu 16.04 LTS) dostanete na výstupu chybu. Kali Linux takové problémy nemá (není divu, jedná se o distribuci zaměřenou na penetrační testování), takže zde můžete sslscan bez obav použít. Fanoušci ostatních linuxových distribucí mohou použít verzi sslscan z GitHubu.

Výstup z nástroje sslscan pak může vypadat takto:

# sslscan www.linuxservices.cz
Version: 1.11.11-static
OpenSSL 1.0.2-chacha (1.0.2g-dev)
Connected to 212.158.157.4
Testing SSL server www.linuxservices.cz on port 443 using SNI name www.linuxservices.cz

 TLS Fallback SCSV:
Server supports TLS Fallback SCSV

 TLS renegotiation:
Session renegotiation not supported

 TLS Compression:
Compression disabled

 Heartbleed:
TLS 1.2 not vulnerable to heartbleed
TLS 1.1 not vulnerable to heartbleed
TLS 1.0 not vulnerable to heartbleed

 Supported Server Cipher(s):
Preferred TLSv1.2  256 bits  ECDHE-ECDSA-AES256-GCM-SHA384 Curve P-256 DHE 256
Accepted  TLSv1.2  128 bits  ECDHE-ECDSA-AES128-GCM-SHA256 Curve P-256 DHE 256

 SSL Certificate:
Signature Algorithm: ecdsa-with-SHA256
Subject:  www.linuxservices.cz
Altnames: DNS:www.linuxservices.cz, DNS:mail.linuxservices.cz, DNS:oa.linuxservices.cz
Issuer:   COMODO ECC Domain Validation Secure Server CA

Not valid before: Feb 18 00:00:00 2016 GMT
Not valid after:  Feb  3 23:59:59 2019 GMT

Výstupní hodnoty jsou záměrně podbarveny. Modře jsou označeny jednotlivé „odstavce“, zeleně pak hodnoty, které jsou v pořádku. Pokud se vás bude skript bude snažit upozornit na nebezpečí, podbarví výstup červeně.

Test parametrů SSL/TLS pomocí webové služby

I takový test je samozřejmě k dispozici, konkrétně na webu SSL Labs. Tam zadejte doménové jméno testovaného serveru, pohodlně se usaďte a čekejte. Bude to chvilku trvat. Pokud váš server obdrží alespoň hodnocení A (zelené), pak je vše v pořádku. Výsledkem bude zhruba čtyřstránkový (velmi podrobný) protokol. Jeho hlavička vypadá takto:


Serverový certifikát

Serverový certifikát je vlastně parametrický soubor na straně serveru, který obsahuje digitálně podepsaný veřejný šifrovací klíč tohoto serveru. Obsahuje samozřejmě i řadu dalších údajů a parametrů jako jsou údaje o majiteli veřejného klíče nebo údaje o vydavateli certifikátu, obsahuje také parametry nezbytné pro vytvoření šifrovaného spojení mezi serverem a klientem.

V zásadě máme dvě možnosti:

  • self-signed certifikát
  • Certifikát podepsaný certifikační autoritou

Self-signed certifikát

Vytvoříme si sami tzv. self-signed certifikát. Ten není podepsán žádnou certifikační autoritou, ale podepsali jsme si jej sami. Takový certifikát je vhodný pro vývojové a testovací prostředí nebo jako dočasné řešení. Výhodou tohoto řešení je ovšem fakt, že můžeme poměrně široce ovlivňovat parametry šifrovacích mechanismů (a to až na úroveň konkrétních eliptických křivek).

Nový self-signed certifikát pak vygenerujeme z příkazové řádky takto (celý příkaz je na jednom řádku):

# sudo openssl req -new -days 365 -nodes -x509  \
-newkey ec -pkeyopt ec_paramgen_curve:prime256v1 \
-subj "/C=CZ/ST=CZ/L=Prague/O=Dis/CN=www.example.com" \
-keyout /etc/ssl/private/www.example.com.key \
-out /etc/ssl/certs/www.example.com.cert

Kde:

  • days – počet dnů platnosti certifikátu
  • nodes – certifikát nebude vyžadovat heslo
  • x509 – vytváříme self signed certifikát
  • newkey ec – EC (Elliptic curve) key processing, budeme generovat 2048 bitový privátní klíč
  • pkeyopt ec_paramgen_curve – zadáme označení eliptické křivky, kterou si přejeme používat
  • prime256v1 je označení použité eliptické křivky. Seznam podporovaných křivek získáte příkazem openssl ecparam -list_curves
  • subj – údaje o vlastníkovi certifikátu
  • keyout – umístění privátního klíče
  • out – umístění certifikátu

Netřeba zdůrazňovat, že privátní klíč i certifikát by měly být na souborovém systém serveru umístěny v oblasti, kam může jen root.

Ověření vlastností klíče a certifikátu

Opět tak můžeme učinit z příkazové řádky. Napřed klíč:

# sudo openssl ecparam -in /etc/ssl/private/www.example.com.key -text -noout

Výstup vypadá takto:

unable to load elliptic curve parameters
139938282350232:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:701:Expecting: EC PARAMETERS

S parametry eliptické křivky má openssl pravdu, tyto údaje jsou totiž (v našem případě) obsaženy v certifikátu. Provedeme tedy kontrolu certifikátu:

# sudo openssl x509 -in /etc/ssl/certs/www.example.com.cert -text -noout

Výstup vypadá takto:

Certificate:
   Data:
       Version: 3 (0x2)
       Serial Number: 11852754468677487082 (0xa47d7164037209ea)
   Signature Algorithm: ecdsa-with-SHA256
       Issuer: C=CZ, ST=CZ, L=Prague, O=Dis, CN=www.example.com
       Validity
           Not Before: Jul 27 08:30:18 2018 GMT
           Not After : Jul 27 08:30:18 2019 GMT
       Subject: C=CZ, ST=CZ, L=Prague, O=Dis, CN=www.example.com
       Subject Public Key Info:
           Public Key Algorithm: id-ecPublicKey
               Public-Key: (256 bit)
               pub:
                   04:a8:72:f0:3c:a2:ce:7c:c7:e6:ea:0e:91:02:72:
                   77:75:f4:b0:9f:2b:4e:dc:05:89:25:25:87:c5:2f:
                   4c:fa:b7:14:34:3a:63:0f:8e:6f:bd:34:b1:8c:98:
                   f5:de:65:a7:ff:6c:ef:98:9d:d1:ff:1d:5b:07:33:
                   aa:b3:34:a9:70
               Field Type: prime-field
               Prime:
                   00:ff:ff:ff:ff:00:00:00:01:00:00:00:00:00:00:
                   00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                   ff:ff:ff
               A:
                   00:ff:ff:ff:ff:00:00:00:01:00:00:00:00:00:00:
                   00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                   ff:ff:fc
               B:
                   5a:c6:35:d8:aa:3a:93:e7:b3:eb:bd:55:76:98:86:
                   bc:65:1d:06:b0:cc:53:b0:f6:3b:ce:3c:3e:27:d2:
                   60:4b
               Generator (uncompressed):
                   04:6b:17:d1:f2:e1:2c:42:47:f8:bc:e6:e5:63:a4:
                   40:f2:77:03:7d:81:2d:eb:33:a0:f4:a1:39:45:d8:
                   98:c2:96:4f:e3:42:e2:fe:1a:7f:9b:8e:e7:eb:4a:
                   7c:0f:9e:16:2b:ce:33:57:6b:31:5e:ce:cb:b6:40:
                   68:37:bf:51:f5
               Order:
                   00:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:
                   ff:ff:bc:e6:fa:ad:a7:17:9e:84:f3:b9:ca:c2:fc:
                   63:25:51
               Cofactor:  1 (0x1)
               Seed:
                   c4:9d:36:08:86:e7:04:93:6a:66:78:e1:13:9d:26:
                   b7:81:9f:7e:90
       X509v3 extensions:
           X509v3 Subject Key Identifier:
               18:79:43:7B:33:CC:7F:6C:DD:2F:9D:AF:DF:EE:F0:57:0F:9E:6D:5C
           X509v3 Authority Key Identifier:
               keyid:18:79:43:7B:33:CC:7F:6C:DD:2F:9D:AF:DF:EE:F0:57:0F:9E:6D:5C

           X509v3 Basic Constraints:
               CA:TRUE
   Signature Algorithm: ecdsa-with-SHA256
        30:44:02:20:25:e3:3e:ea:37:ec:3d:c3:c0:7f:df:0a:ce:61:
        9f:ce:17:1c:dd:ca:13:b9:50:84:4f:20:28:0e:de:3e:37:86:
        02:20:7e:00:a2:9d:ac:54:aa:d6:46:24:a8:29:62:b4:31:8f:
        fb:49:2f:58:e5:1d:5a:44:5e:e7:e2:10:79:30:c4:62

Certifikát podepsaný certifikační autoritou

Máme samozřejmě na mysli důvěryhodnou certifikační autoritu. Zde pozor, nemusejí to nutně být ty certifikační autority, které má předinstalován váš prohlížeč, to je zkrátka život.

Pokud se poohlížíte po jednoduchém a bezplatném řešení, zkuste Let's Encrypt. Vyžádání a instalace certifikátu není složitá, zvládne ji i neznalá obsluha. Pro dodržení bezpečnostních politik ale doporučuji provádět instalaci certifikátu pod uživatelem root.

Podrobné návody naleznete přímo tady na Rootu pod nálepkou Let's Encrypt.

Nevýhodou je, že Let's Encrypt Authority v současné době nepoužívá ve výchozím nastavení eliptické křivky. Pokud tedy trváte na eliptických křivkách, pak budete muset příslušný parametr doplnit ručně.

Pozor: Konfigurační skript Let'S Encrypt má ošklivý zvyk upravovat více parametrů, než je zdrávo. Do konfiguračního souboru /etc/apache2/sites-available/xxx-site.cz.conf pak je schopen vložit toto:

SSLCertificateFile /etc/letsencrypt/live/xxx-site.cz/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/xxx-site/privkey.pem
#Include /etc/letsencrypt/options-ssl-apache.conf

Řádek s Include  raději hned zakomentujte (v příkladu výše již zakomentováno je), jinak se budete podivovat nad tím, proč má váš Apache konfiguraci, kterou jste si přece nenastavili.

Pokud máte pocit, že jste vše nastavili správně a server se nechová korektně, pak se ještě podívejte do konfiguračního souboru /etc/apache2/apache2.conf a hledejte parametr:

# Include generic snippets of statements
IncludeOptional conf-enabled/*.conf

V adresáři /etc/apache2/conf-enabled/ se pak nejspíš bude nacházet konfigurační soubor ssl-params.conf, který je pravděpodobně na vině. Opravte konfiguraci i v tomto souboru (nebo jej celý smažte) a restartujte Apache příkazem:

MIF obecny

# systemctl restart apache2

Zkontrolujte, zda démon apache2 opravdu běží:

# systemctl status apache2

Nyní opakujte měření parametrů. Vše by již mělo být tak, jak jste si nastavili.