Jak zlepšit výkon HTTPS serveru v Node.js

V dnešním příspěvku se ponoříme do protokolu TLS a ukážeme si, které možnosti nastavení HTTPS serveru v Node.js mají vliv na jeho výkonnost.

SSL, TLS, HTTPS

Na úvod začněme stručnou rekapitulací protokolů pro zabezpečení spojení mezi klientem a serverem.

  • SSL je zkratkou pro Secure Socket Layer. Protokol byl vytvořený v polovině devadesátých let společností Netscape, poměrně brzo byl nahrazený TLS.
  • TLS označuje Transport Security Layer. Jedná se o standard udržovaný organizací IETF, který odstraňuje nedostatky a bezpečnostní slabiny protokolu SSL.
  • Oba protokoly SSL a TLS fungují na úrovni TCP sockets, poskytují prostředky k převedení otevřeného toku (plaintext stream) na plně šifrovaný kanál.
  • HTTS, nebo-li HTTP Secure, je kombinací HTTP protokolu komunikujícím přes SSL nebo TLS kanál.

Znovupoužití TLS Session

Založení nového zabezpečeného kanálu vyžaduje dvě kolečka mezi klientem a serverem. Navíc klient i server musí vykonat výpočetně náročné kryptografické operace, které jsou potřebné pro vytvoření sdíleného tajného klíče, který se dál používá pro šifrování dat.

Znovupoužití session funguje na principu opětovného využití stejné konfigurace, která byla použita pro předchozí spojení. Ušetří nám jedno kolečko a umožní vynechat drahou přípravu kryptografických parametrů. Tento mechanizmus je jedním z nejdůležitějších způsobů jak zvýšit výkonnost SSL/TLS komunikace.

Poznámka: pozor na záměnu pojmu TLS session se session používanou ve webových aplikacích pro zachování stavu mezi dotazy. Jedná se o dva různé a nesouvisející koncepty.

Jsou dva způsoby jak znovu použít TLS session:

  • Identifikátor session (Session Identifier) je součástí SSL i TLS standardů a měl by být podporován všemi implementacemi. Od TLS serveru se vyžaduje, aby si udržoval seznam všech platných session, a pak na základě identifikátoru prezentovaném klientem byl schopen nastavit (obnovit) příslušné parametry spojení. Jak uvidíme později, tento požadavek znamená pro Node.js servery práci navíc.
  • Session lístek (Session Ticket) je rozšířením protokolu TLS, které umožňuje zakódovat všechny potřebné údaje do jednoho lístku (ticketu), čímž řeší problém sdílení platných session mezi servery v distribuovaném prostředí. Když se klient představí serveru se správným lístkem, server dokáže obnovit session aniž by se musel podívat do externí keše platných session. Toto rozšíření zatím není implementováno ve všech TLS klientech. Klienti podporující session tickets jsou prohlížeče Google Chrome a Mozilla Firefox, knihovny openssl and gnutls. Prohlížeče Internet Explorer a Safari tuto funkcionalitu zatím nepodporují.

Podrobnější informace lze nalézt ve výborném článku (v angličtině).

Konfigurace Node.js serveru pro znovupoužití session

Znovupoužití session přes session ticket funguje samo, implementace je z pohledu vašeho kódu úplně transparentní a při běhu v jednom procesu funguje bezvadně. Když dojde na nativní cluster, chyba #5871 ve verzi v0.10 znamená, že procesy v clusteru neakceptují lístky vydané sousedními procesy. Protože však rozdělení požadavků mezi procesy není ve verzi v0.10 rovnoměrné (většina spojení skončí u jednoho nebo dvou nejvytíženějších procesů), dopad tohoto problému by neměl být příliš velký. Chyba je opravena ve verzi v0.11.

Znovupoužití session přes session identifikátory vyžaduje, aby vaše aplikace implementovala úložiště platných session (session store) a obsloužila události newSession a resumeSession. Následující kód demonstruje možnou implementaci pro TLS server běžící v jednom procesu. Poznamenejme, že HTTPS server je potomkem TLS serveru, takže stejný mechanizmus lze použít pro nastavení HTTP serveru.

var tls = require('tls');

var tlsSessionStore = {};
// TODO - implement removal of expired sessions

var opts = { /* configure certificates, etc. */ };
var server = tls.createServer(opts, tlsConnectionHandler);

server.on('newSession', function(id, data) {
  tlsSessionStore[id] = data;
});
server.on('resumeSession', function(id, cb) {
  cb(null, tlsSessionStore[id] || null);
});

server.listen(4433);

Když provozujeme cluster z vícero procesů, potřebujeme sdílet úložiště session mezi všemi procesy. Nejjednodušší řešení je použít balíček strong-cluster-tls-store, který je postavený nad posíláním zpráv mezi hlavním procesem a pracovními procesy a nevyžaduje tak žádné externí služby typu Redis. Podívejme se, jak nakonfigurovat HTTPS v Express aplikaci bežící v clusteru.

var https = require('https');
var express = require('express');
var shareTlsSessions = require('strong-cluster-tls-store');

if (cluster.isMaster) {
  // Setup your master and fork workers.
} else {
  // Start the server and configure TLS sessions sharing

  var app = express();
  // configure the app

  var httpsOpts = { /* configure certificates, etc. */ }
  var server = https.createServer(httpsOpts, app);
  shareTlsSessions(server);

  server.listen(port);
  // etc.
}

Tož to bylo jednoduché, že?

Malé upozornění: současná stabilní verze Node (v0.10) obsahuje chybu, kdy server vyvolá událost resumeSession i v případě, kdy session bude obnovena ze session lístku (#5872). To znamená, že zavedení sdíleného úložiště nejspíš zpomalí proces obnovení session. V závislosti na tom, jak velká část vašich klientů podporuje a nepodporuje TLS session lístky, se může stát, že lepším řešením bude vůbec nepoužívat sdílené úložiště.

Doporučuji, abyste sledovali výkon vaší aplikace a zjistili sami, jestli použití sdíleného úložiště pro TLS sessions přinese zrychlení. Pokud hledáte šikovný monitorovací nástroj, můžete vyzkoušet StrongOps (donedávna NodeFly).

Ověření konfigurace

Když máme správně nakonfigurovanou aplikaci, pojďme ověřit, že server skutečně umožní znovupoužití té samé session. Použijeme k tomu nástroj z balíčku openssl, který je součástí Mac OS X a taky většiny Linuxových distribucí. Ukázky předpokládají, že TLS nebo HTTPS server běží a poslouchá na portu 3000.

Poznámka: verze openssl dodávána s Mac OS X je snad ještě z minulého století a nefunguje moc dobře s verzí používanou v Node. Před provedením následujícího testu by bylo vhodné povýšit na aktuální verzi, například nainstalováním balíčku z homebrew.

  1. Zkontrolujte verzi openssl, potřebujeme alespoň 1.0
    $ openssl version
    OpenSSL 1.0.1e 11 Feb 2013
    
  2. Navážeme několik spojení se znovupoužitím té samé TLS session. Test ukončíme klávesovou zkratkou Ctrl+C.
    $ openssl s_client  -reconnect -port 3000 2>&1 \
    | grep "^\(New\|Reused\)"
    New, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384
    Reused, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384
    Reused, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384
    Reused, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384
    Reused, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384
    Reused, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384
    ^C
    
  3. Zopakujeme ten samý test, ale zakážeme klientovi používat TLS session ticket.
    $ openssl s_client  -reconnect -port 3000 2>&1 -no_ticket \
    | grep "^\(New\|Reused\)"
    New, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384
    Reused, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384
    Reused, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384
    Reused, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384
    Reused, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384
    Reused, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384
    ^C
    

Z obou výstupů je vidět, že první spojení vytvořilo novou session a následujících pět spojení tuto session znovu použilo.

Závěrem

Tento článek je překladem anglického originálu, který vyšel na firemním blogu StrongLoop. Podívejte se taky na infografiku o stavu Node.js nebo video Node.js je tady!, ve kterém dva hlavní vývojáři Node.js vysvětlují naši misi zjednodušit vývoj mobilních aplikací pro Enterprise.

10 thoughts on “Jak zlepšit výkon HTTPS serveru v Node.js
  1. Poznámka: verze openssl dodávána s Mac OS X je snad ještě z minulého století a nefunguje moc dobře s verzí používanou v Node. Před provedením následujícího testu by bylo vhodné povýšit na aktuální verzi, například nainstalováním balíčku z homebrew.

    Apple označil openSSL za deprecated už v OS X 10.7 (červen 2011) nahrazuje ji “Common Crypto”, kterou samo vyvíjí, takže Node.js by mělo na OS X používat spíše tuto knihovnu. http://www.opensource.apple.com/source/CommonCrypto/CommonCrypto-60049/

  2. Feelings that may keep you from writing your book. Writing an essay is a tough problem to do to get a student and also for a typical man who doesn’t possess the particular comprehension of the language and the grammar that ought to be utilised in an essay.
    Content writing can also be a sort of essay writing, only you must be cautious with the rules, if you believe that it’s possible to write essay correctly then readily you may also write the content, it’s not in any manner a huge thing. It is the chief part of the prewriting procedure of an essay.
    Personalised assignment writing service company will probably have their own sites Online services are somewhat more dependable and affordable too.
    You might also need to suggest more research or comment on things that it wasn’t possible that you discuss in the paper. The writing profession consists of many perks. In case you have any financial essay writing difficulty, let us know for we will aid you with writings which are quality and which are free from plagiarism.
    So, once you are doing your homework you should be aware you have set all required information regarding your research. A student looking for quality financial research papers ought to go to an organization with a great reputation on filing its job punctually.
    Whatever the consequences, the expression paper writing service business will nonetheless grow. Internet isn’t only alternative technique to conventional procedures of music supply, but additionally a fantastic prospect for artists and music-recording businesses to expose these goods to broad public. The writing service must additionally have a guarantee that all work is original and distinctive from many other content.
    http://batphuxeoto.net/the-pitfall-of-writing-essay-service/

  3. Simply wish to say your article is as surprising. The clarity for your put up is just
    cool and i can think you are a professional in this subject.
    Well together with your permission let me to grab your RSS
    feed to stay updated with forthcoming post. Thanks 1,000,000 and please carry on the gratifying work.

  4. Хэлоу, если вы играете на ставках,
    прогноз на футбол сегодня от экспертов рекомендую вам контакты надежных аналитиков
    они всегда грабят букмекеров, и помогут вам всем заработать на ставках реальные
    девиденты прогнозы составляют каждый день! контакты этой бригады дальше по ссылке:
    http://experts-betting-win.com/ и если скажите что вы от Френка то получите хорошие бонусы!

Blog byl staticky vyexportován, nové komentáře již nelze přidávat.