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:
# 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.