Pro konfiguraci HTTPS serveru je třeba povolit parametr ssl na poslouchajících soketech v bloku server a také zadat umístění souborů s certifikátem serveru a tajným klíčem:
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate www.example.com.crt;
ssl_certificate_key www.example.com.key;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
...
}
Certifikát serveru je veřejný. Odesílá se každému klientovi, který se připojuje k serveru. Tajný klíč by měl být uložen v souboru s omezeným přístupem (práva přístupu musí umožňovat hlavnímu procesu nginx tento soubor číst). Tajný klíč lze také uložit do stejného souboru jako certifikát:
ssl_certificate www.example.com.cert;
ssl_certificate_key www.example.com.cert;
při čemž je třeba omezit i práva přístupu k tomuto souboru. Ačkoli jsou certifikát i klíč uloženy ve stejném souboru, klientovi je odesílán pouze certifikát.
Pomocí direktiv ssl_protocols a ssl_ciphers lze omezit připojení tak, aby používala pouze „silné“ verze a šifry SSL/TLS. Od verze 1.0.5 nginx ve výchozím nastavení používá „ssl_protocols SSLv3 TLSv1“ a „ssl_ciphers HIGH:!aNULL:!MD5“, takže jejich explicitní nastavení má smysl pouze pro starší verze nginx. Od verzí 1.1.13 a 1.0.12 nginx ve výchozím nastavení používá „ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2“.
Je známo, že šifry s režimem CBC jsou zranitelné vůči řadě útoků, zejména vůči útoku BEAST (viz CVE-2011-3389). Nastavení šifer lze změnit tak, aby byl preferován RC4-SHA:
ssl_ciphers RC4:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
Optimalizace HTTPS serveru
SSL operace spotřebovávají další zdroje procesoru. Na multiprocesorových systémech by mělo být spuštěno více pracovních procesů, a to nejméně podle počtu dostupných procesorových jader. Nejvíce náročnou operací pro procesor je SSL handshake, během kterého se generují kryptografické parametry relace. Existují dva způsoby, jak snížit počet těchto operací prováděných pro každého klienta: použití trvalých (keepalive) připojení, která umožňují zpracovat více požadavků v rámci jednoho připojení, a opětovné použití parametrů SSL relace, aby se předešlo nutnosti provádět SSL handshake pro paralelní a následná připojení. Relace jsou uloženy v mezipaměti SSL relací, sdílené mezi pracovními procesy a konfigurovatelné direktivou ssl_session_cache. Do 1 MB mezipaměti se vejme přibližně 4000 relací. Výchozí časový limit mezipaměti je 5 minut. Lze jej prodloužit pomocí direktivy ssl_session_timeout. Níže je uveden příklad konfigurace optimalizované pro vícejádrový systém se sdílenou 10MB mezipamětí relací:
worker_processes auto;
http {
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
server {
listen 443 ssl;
server_name www.example.com;
keepalive_timeout 70;
ssl_certificate www.example.com.crt;
ssl_certificate_key www.example.com.key;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
...
Řetězce SSL certifikátů
Některé prohlížeče mohou zobrazovat upozornění na certifikát podepsaný obecně známým certifikačním úřadem, zatímco jiné prohlížeče tento stejný certifikát bez problémů přijmou. K tomu dochází proto, že certifikační úřad, který certifikát vydal, jej podepsal mezilehlým certifikátem, který není obsažen v databázi certifikátů obecně známých důvěryhodných certifikačních úřadů šířené spolu s prohlížečem. V takovém případě certifikační úřad poskytuje „řetězec“ certifikátů, který by měl být připojen k serverovému certifikátu. Serverový certifikát by měl být v kombinovaném souboru umístěn před řetězcem certifikátů:
$ cat www.example.com.crt bundle.crt > www.example.com.chained.crt
Výsledný soubor by měl být uveden v direktivě ssl_certificate:
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate www.example.com.chained.crt;
ssl_certificate_key www.example.com.key;
...
}
Pokud byl serverový certifikát a řetězec certifikátů spojeny ve špatném pořadí, nginx odmítne spuštění a vypíše chybovou zprávu:
SSL_CTX_use_PrivateKey_file(" ... /www.example.com.key") failed
(SSL: error:0B080074:x509 certificate routines:
X509_check_private_key:key values mismatch)
protože se nginx pokusí použít tajný klíč s prvním certifikátem z řetězce místo serverového certifikátu.
Prohlížeče obvykle ukládají získané mezilehlé certifikáty podepsané důvěryhodnými certifikačními úřady, takže aktivně používané prohlížeče již mohou mít požadované mezilehlé certifikáty a nezobrazí upozornění na certifikát zaslaný bez připojeného řetězce certifikátů. Ověřit, že server zasílá kompletní řetězec certifikátů, lze pomocí příkazové řádky openssl, například:
$ openssl s_client -connect www.godaddy.com:443
...
Certificate chain
0 s:/C=US/ST=Arizona/L=Scottsdale/1.3.6.1.4.1.311.60.2.1.3=US
/1.3.6.1.4.1.311.60.2.1.2=AZ/O=GoDaddy.com, Inc
/OU=MIS Department/CN=www.GoDaddy.com
/serialNumber=0796928-7/2.5.4.15=V1.0, Clause 5.(b)
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc.
/OU=http://certificates.godaddy.com/repository
/CN=Go Daddy Secure Certification Authority
/serialNumber=07969287
1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc.
/OU=http://certificates.godaddy.com/repository
/CN=Go Daddy Secure Certification Authority
/serialNumber=07969287
i:/C=US/O=The Go Daddy Group, Inc.
/OU=Go Daddy Class 2 Certification Authority
2 s:/C=US/O=The Go Daddy Group, Inc.
/OU=Go Daddy Class 2 Certification Authority
i:/L=ValiCert Validation Network/O=ValiCert, Inc.
/OU=ValiCert Class 2 Policy Validation Authority
/CN=http://www.valicert.com//emailAddress=info@valicert.com
...
V tomto příkladu subjekt („s“) certifikátu č. 0 serveru www.GoDaddy.com je podepsán vydavatelem („i“), který je zároveň subjektem certifikátu č. 1, podepsaným vydavatelem, který je zároveň subjektem certifikátu č. 2, podepsaným obecně známým vydavatelem ValiCert, Inc., jehož certifikát je uložen ve vestavěné databázi certifikátů prohlížečů (která se nachází v temné skříni v domě, který postavil Jakub).
Pokud by řetězec certifikátů nebyl přidán, byl by zobrazen pouze certifikát serveru č. 0.
Jeden HTTP/HTTPS server
Lze nakonfigurovat jeden server, který obsluhuje jak HTTP, tak HTTPS požadavky:
server {
listen 80;
listen 443 ssl;
server_name www.example.com;
ssl_certificate www.example.com.crt;
ssl_certificate_key www.example.com.key;
...
}
Do verze 0.7.14 nebylo možné SSL povolit selektivně pro jednotlivé naslouchající sokety, jak je ukázáno výše. SSL bylo možné povolit pouze pro celý server pomocí direktivy ssl, což neumožňovalo nakonfigurovat jeden HTTP/HTTPS server. Pro řešení tohoto problému byl přidán parametr ssl direktivy listen. Proto se používání direktivy ssl v moderních verzích nedoporučuje.
Výběr HTTPS serveru podle jména
Typický problém nastává při konfiguraci dvou nebo více HTTPS serverů naslouchajících na stejné IP adrese:
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate www.example.com.crt;
...
}
server {
listen 443 ssl;
server_name www.example.org;
ssl_certificate www.example.org.crt;
...
}
V této konfiguraci obdrží prohlížeč výchozí certifikát serveru, tj. www.example.com, bez ohledu na požadované jméno serveru. Je to dáno chováním protokolu SSL. SSL spojení je navázáno dříve, než prohlížeč odešle HTTP požadavek, a nginx nezná požadované jméno serveru. Proto může nabídnout pouze výchozí certifikát serveru.
Nejstarším a nejspolehlivějším způsobem řešení tohoto problému je přiřazení každému HTTPS serveru vlastní IP adresy:
server {
listen 192.168.1.1:443 ssl;
server_name www.example.com;
ssl_certificate www.example.com.crt;
...
}
server {
listen 192.168.1.2:443 ssl;
server_name www.example.org;
ssl_certificate www.example.org.crt;
...
}
SSL certifikát s více jmény
Existují i jiné způsoby, které umožňují používat stejnou IP adresu současně pro více HTTPS serverů. Všechny však mají své nevýhody. Jedním z takových způsobů je použití certifikátu s více jmény v poli SubjectAltName certifikátu, např.www.example.com a www.example.org. Délka pole SubjectAltName je však omezena.
Dalším způsobem je použití wildcard certifikátu, např. *.example.org. Tento certifikát chrání všechny subdomény uvedené domény, ale pouze na dané úrovni. Pro tento certifikát vyhovuje www.example.org, ale nevyhovují example.org a www.sub.example.org. Dva výše uvedené způsoby lze kombinovat. Certifikát může současně obsahovat přesná i wildcard jména v poli SubjectAltName, např. example.org a *.example.org.
Je lepší umístit informace o souboru certifikátu s více jmény a souboru s jeho tajným klíčem na úrovni konfigurace http, aby všechny servery zdědily jeho jedinou kopii v paměti:
ssl_certificate common.crt;
ssl_certificate_key common.key;
server {
listen 443 ssl;
server_name www.example.com;
...
}
server {
listen 443 ssl;
server_name www.example.org;
...
}
