Zephyrnet-logo

SSL / TLS gebruiken met Node.js

Datum:

In 2020 is er geen reden waarom uw website geen HTTPS gebruikt. Bezoekers verwachten het, Google gebruikt het als rankingfactor en browsermakers zullen graag de sites die het niet gebruiken een naam geven en beschamen.

In deze tutorial zal ik je een praktisch voorbeeld geven van hoe je een kunt toevoegen Laten we versleutelen-Genereerd certificaat naar uw Express.js-server.

Maar onze sites en apps beschermen met HTTPS is niet voldoende. We moeten ook versleutelde verbindingen eisen van de servers waarmee we praten. We zullen zien dat er mogelijkheden zijn om de SSL / TLS-laag te activeren, zelfs als deze niet standaard is ingeschakeld.

Opmerking: als je instructies zoekt voor het instellen van SSL met NGINX wanneer je het configureert om te werken als een reverse proxy voor een Node-app, bekijk dan onze snelle tip, "NGINX en SSL configureren met Node.js'.

Laten we beginnen met een kort overzicht van de huidige staat van HTTPS.

HTTPS Everywhere

De HTTP / 2-specificatie werd in mei 7540 gepubliceerd als RFC 2015, wat betekent dat het op dit moment deel uitmaakt van de standaard. Dit was een belangrijke mijlpaal. Nu kunnen we allemaal onze servers upgraden om HTTP / 2 te gebruiken. Een van de belangrijkste aspecten is de achterwaartse compatibiliteit met HTTP 1.1 en het onderhandelingsmechanisme om een ​​ander protocol te kiezen. Hoewel de standaard geen verplichte codering specificeert, ondersteunt momenteel geen enkele browser HTTP / 2 onversleuteld. Dit geeft HTTPS weer een boost. Eindelijk krijgen we overal HTTPS!

Hoe ziet onze stapel er eigenlijk uit? Vanuit het perspectief van een website die in de browser draait (op applicatieniveau), moeten we de volgende lagen doorlopen om het IP-niveau te bereiken:

  1. Client-browser
  2. HTTP
  3. SSL / TLS
  4. TCP
  5. IP

HTTPS is niets meer dan het HTTP-protocol bovenop SSL / TLS. Daarom zijn alle regels van HTTP nog steeds van toepassing. Wat geeft deze extra laag ons eigenlijk? Er zijn meerdere voordelen: we krijgen authenticatie door het hebben van sleutels en certificaten; een zekere vorm van privacy en vertrouwelijkheid wordt gegarandeerd, aangezien de verbinding op een asymmetrische manier wordt versleuteld; en de gegevensintegriteit blijft ook behouden, aangezien verzonden gegevens tijdens het transport niet kunnen worden gewijzigd.

Een van de meest voorkomende mythen is dat het gebruik van SSL / TLS rekenkundig duur is en de server vertraagt. Dit is zeker niet meer waar. We hebben ook geen gespecialiseerde hardware nodig met cryptografie-eenheden. Zelfs voor Google, de SSL / TLS-laag is verantwoordelijk voor minder dan 1% van de CPU-belasting en de netwerkoverhead van HTTPS in vergelijking met HTTP is minder dan 2%. Al met al zou het niet logisch zijn om HTTPS af te zien omwille van een beetje overhead.

Zoals Ilya Grigorik het uitdrukt, is er maar één prestatieprobleem:

De meest recente versie is TLS 1.3. TLS is de opvolger van SSL, die beschikbaar is in de nieuwste versie SSL 3.0. De wijzigingen van SSL naar TLS sluiten interoperabiliteit uit, maar de basisprocedure is onveranderd. We hebben drie verschillende gecodeerde kanalen. De eerste is een openbare sleutelinfrastructuur voor certificaatketens. De tweede biedt cryptografie met openbare sleutels voor sleuteluitwisselingen. Ten slotte is de derde symmetrisch. Hier hebben we cryptografie voor gegevensoverdracht.

TLS 1.3 gebruikt hashing voor enkele belangrijke bewerkingen. Theoretisch is het mogelijk om elk hash-algoritme te gebruiken, maar het wordt ten zeerste aanbevolen om SHA2 of een sterker algoritme te gebruiken. SHA1 is al lang een standaard, maar is sinds kort verouderd.

HTTPS krijgt ook meer aandacht voor klanten. Zorgen over privacy en veiligheid zijn er altijd geweest, maar met de groeiende hoeveelheid online toegankelijke gegevens en diensten, maken mensen zich steeds meer zorgen. Voor die sites die het niet implementeren, is er een handige browserextensie - HTTPS Everywhere van de EFF - die onze communicatie met de meeste websites versleutelt.

HTTPS-overal

De makers beseften dat veel websites HTTPS slechts gedeeltelijk aanbieden. Met de plug-in kunnen we verzoeken herschrijven voor die sites die slechts gedeeltelijke HTTPS-ondersteuning bieden. Als alternatief kunnen we ook HTTP helemaal blokkeren (zie de schermafbeelding hierboven).

Basiscommunicatie

Het validatieproces van het certificaat omvat het valideren van de handtekening en het verlopen van het certificaat. We moeten ook controleren of het aan een vertrouwde root is gekoppeld. Ten slotte moeten we controleren of het is ingetrokken. Er zijn toegewijde, vertrouwde autoriteiten in de wereld die certificaten verlenen. Indien een van deze in gevaar zou komen, zouden alle andere certificaten van de genoemde autoriteit worden ingetrokken.

Het volgordediagram voor een HTTPS-handshake ziet er als volgt uit. We beginnen met de initialisatie van de klant, gevolgd door een bericht met het certificaat en de sleuteluitwisseling. Nadat de server zijn voltooide pakket heeft verzonden, kan de client de sleuteluitwisseling en de overdracht van coderingsspecificaties starten. Op dit punt is de klant klaar. Ten slotte bevestigt de server de selectie van de cijferspecificatie en sluit de handdruk.

HTTPS-volgorde

De hele reeks wordt onafhankelijk van HTTP geactiveerd. Als we besluiten om HTTPS te gebruiken, wordt alleen de socketverwerking gewijzigd. De client verzendt nog steeds HTTP-verzoeken, maar de socket voert de eerder beschreven handshake uit en versleutelt de inhoud (header en body).

Dus wat hebben we nodig om SSL / TLS te laten werken met een Express.js-server?

HTTPS

Standaard bedient Node.js inhoud via HTTP. Maar er is ook een HTTPS-module die we moeten gebruiken om via een beveiligd kanaal met de klant te communiceren. Dit is een ingebouwde module en het gebruik lijkt erg op hoe we de HTTP-module gebruiken:

const https = require("https"), fs = require("fs"); const options = { key: fs.readFileSync("/srv/www/keys/my-site-key.pem"), cert: fs.readFileSync("/srv/www/keys/chain.pem")
}; const app = express(); app.use((req, res) => { res.writeHead(200); res.end("hello worldn");
}); app.listen(8000); https.createServer(options, app).listen(8080);

Negeer de /srv/www/keys/my-site-key.pem en en /srv/www/keys/chain.pem bestanden op dit moment. Dat zijn de SSL-certificaten die we moeten genereren, wat we later zullen doen. Dit is het deel dat is veranderd met Let's Encrypt. Voorheen moesten we een privé / openbare sleutelpaar genereren, deze naar een vertrouwde autoriteit sturen, ze betalen en waarschijnlijk even wachten om een ​​SSL-certificaat te krijgen. Tegenwoordig genereert en valideert Let's Encrypt direct uw certificaten gratis!

Certificaten genereren

Certbot

De TLS-specificatie vereist een certificaat, dat is ondertekend door een vertrouwde certificeringsinstantie (CA). De CA zorgt ervoor dat de certificaathouder werkelijk is wie hij beweert te zijn. Dus eigenlijk betekent het dat wanneer u het groene slotpictogram (of een ander groenachtig teken aan de linkerkant van de URL in uw browser) ziet, de server waarmee u communiceert echt is wie hij beweert te zijn. Als je op facebook.com zit en je ziet een groen slot, is het bijna zeker dat je echt met Facebook communiceert en dat niemand anders je communicatie kan zien - of beter gezegd, niemand anders kan het lezen.

Het is vermeldenswaard dat dit certificaat niet noodzakelijkerwijs hoeft te worden geverifieerd door een autoriteit als Let's Encrypt. Er zijn ook andere betaalde services. U kunt het technisch zelf ondertekenen, maar dan (aangezien u geen vertrouwde CA bent), zullen de gebruikers die uw site bezoeken waarschijnlijk een grote enge waarschuwingsaanbieding zien om ze weer in veiligheid te brengen.

In het volgende voorbeeld gebruiken we de Certbot, die wordt gebruikt om certificaten te genereren en te beheren met Let's Encrypt.

Op de Certbot-site vindt u instructies voor het installeren Certbot voor bijna elke OS / server-combinatie. U moet de opties kiezen die op u van toepassing zijn.

Een veel voorkomende combinatie voor het implementeren van Node-apps is NGINX op de nieuwste LTS Ubuntu en dat is wat ik hier zal gebruiken.

sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update

Webroot

Webroot is een Certbot-plug-in dat, naast de standaardfunctionaliteit van Certbot (die automatisch uw openbare / privé-sleutelpaar genereert en daarvoor een SSL-certificaat genereert), ook de certificaten naar uw webroot-map kopieert en uw server verifieert door een verificatiecode in een verborgen tijdelijke map te plaatsen genaamd .well-known. Om sommige van deze stappen handmatig over te slaan, gebruiken we deze plug-in. De plug-in wordt standaard geïnstalleerd met Certbot. Om onze certificaten te genereren en te verifiëren, voeren we het volgende uit:

certbot certonly --webroot -w /var/www/example/ -d www.example.com -d example.com

Mogelijk moet u deze opdracht uitvoeren als sudo, omdat deze probeert te schrijven /var/log/letsencrypt.

U wordt ook om uw e-mailadres gevraagd. Het is een goed idee om een ​​echt adres in te voeren dat u vaak gebruikt, omdat u een melding krijgt als uw certificaat bijna verloopt. De wisselwerking voor Let's Encrypt die een gratis certificaat afgeeft, is dat het elke drie maanden verloopt. Gelukkig is vernieuwen net zo eenvoudig als het uitvoeren van één simpele opdracht, wat we kunnen toewijzen aan een cron-taak en dan geen zorgen te maken over de vervaldatum. Bovendien is het een goede beveiligingspraktijk om SSL-certificaten te vernieuwen, omdat het aanvallers minder tijd geeft om de codering te verbreken. Soms hebben ontwikkelaars deze cron zelfs zo ingesteld dat deze dagelijks wordt uitgevoerd, wat helemaal prima is en zelfs wordt aanbevolen.

Houd er rekening mee dat u deze opdracht moet uitvoeren op een server waarnaar het domein is opgegeven onder de -d (voor domein) vlag lost op - dat wil zeggen uw productieserver. Zelfs als u de DNS-resolutie in uw lokale hosts-bestand heeft, zal dit niet werken, omdat het domein van buitenaf wordt geverifieerd. Dus als u dit lokaal doet, zal het hoogstwaarschijnlijk mislukken, tenzij u een poort van uw lokale machine naar de buitenwereld hebt geopend en deze achter een domeinnaam laat lopen die naar uw machine wordt omgezet. Dit is een hoogst onwaarschijnlijk scenario.

Last but not least, na het uitvoeren van deze opdracht, bevat de uitvoer paden naar uw privésleutel en certificaatbestanden. Kopieer deze waarden naar het vorige codefragment - naar de cert eigenschap voor certificaat, en de key eigendom voor de sleutel:

// ... const options = { key: fs.readFileSync("/var/www/example/sslcert/privkey.pem"), cert: fs.readFileSync("/var/www/example/sslcert/fullchain.pem") // these paths might differ for you, make sure to copy from the certbot output
}; // ...

Het verbeteren

HTTP Strict Transport Security

Heb je ooit een website gehad waar je bent overgestapt van HTTP naar HTTPS en er waren nog enkele omleidingen die nog steeds omleidden naar HTTP? HTTP Strict Transport Security (HSTS) is een webbeveiligingsbeleidsmechanisme om protocol-downgrade-aanvallen en het kapen van cookies te beperken.

HSTS dwingt de client (browser die toegang heeft tot uw server) effectief om al het verkeer via HTTPS te leiden - een 'veilige of helemaal geen' ideologie!

Express JS staat ons niet toe om deze koptekst standaard toe te voegen, dus we zullen gebruiken Helm, een Node-module waarmee we dit kunnen doen. Installeren Helm door het volgende uit te voeren:

npm install helmet

Dan moeten we het gewoon als middleware toevoegen aan onze Express-server:

const https = require("https"), fs = require("fs"), helmet = require("helmet"); const options = { key: fs.readFileSync("/srv/www/keys/my-site-key.pem"), cert: fs.readFileSync("/srv/www/keys/chain.pem")
}; const app = express(); app.use(helmet()); // Add Helmet as a middleware app.use((req, res) => { res.writeHead(200); res.end("hello worldn");
}); app.listen(8000); https.createServer(options, app).listen(8080);

Diffie – Hellman Strong (re) Parameters

Om een ​​ingewikkelde wiskunde over te slaan, gaan we door met de achtervolging. Eenvoudig gezegd zijn er twee verschillende sleutels die worden gebruikt voor versleuteling: het certificaat dat we krijgen van de certificeringsinstantie en een die wordt gegenereerd door de server voor sleuteluitwisseling. De standaardsleutel voor sleuteluitwisseling (ook wel genoemd Diffie – Hellman sleuteluitwisseling, of DH) gebruikt een "kleinere" sleutel dan die voor het certificaat. Om dit te verhelpen, zullen we een sterke DH-sleutel genereren en deze voor gebruik naar onze beveiligde server sturen.

Om een ​​langere (2048 bit) sleutel te genereren, heb je nodig openssl, die u waarschijnlijk standaard hebt geïnstalleerd. Als je het niet zeker weet, ren dan openssl -v. Als de opdracht niet wordt gevonden, installeer dan openssl door rennen sudo apt install openssl (of bezoek hun downloadpagina hier):

openssl dhparam -out /var/www/example/sslcert/dh-strong.pem 2048

Kopieer vervolgens het pad naar het bestand naar onze configuratie:

// ... const options = { key: fs.readFileSync("/var/www/example/sslcert/privkey.pem"), cert: fs.readFileSync("/var/www/example/sslcert/fullchain.pem"), // these paths might differ for you, make sure to copy from the certbot output dhparam: fs.readFileSync("/var/www/example/sslcert/dh-strong.pem")
}; // ...

Conclusie

In 2020 en daarna is er geen excuus om HTTPS te negeren. De toekomstige richting is duidelijk zichtbaar: HTTPS overal! In Node.js hebben we veel opties voor het gebruik van SSL / TLS. We kunnen onze websites publiceren in HTTPS, we kunnen verzoeken indienen voor gecodeerde websites en we kunnen anderszins niet-vertrouwde certificaten autoriseren.

Bron: https://www.sitepoint.com/how-to-use-ssltls-with-node-js/?utm_source=rss

spot_img

Laatste intelligentie

spot_img