Express.js üzerinde HTTPS'yi etkinleştirme


408

HTTPS'yi düğüm için express.js üzerinde çalıştırmaya çalışıyorum ve anlayamıyorum.

Bu benim app.jskodum.

var express = require('express');
var fs = require('fs');

var privateKey = fs.readFileSync('sslcert/server.key');
var certificate = fs.readFileSync('sslcert/server.crt');

var credentials = {key: privateKey, cert: certificate};


var app = express.createServer(credentials);

app.get('/', function(req,res) {
    res.send('hello');
});

app.listen(8000);

Çalıştırdığımda, yalnızca HTTP isteklerine yanıt veriyor gibi görünüyor.

Basit vanilya node.jstabanlı HTTPS uygulaması yazdım :

var   fs = require("fs"),
      http = require("https");

var privateKey = fs.readFileSync('sslcert/server.key').toString();
var certificate = fs.readFileSync('sslcert/server.crt').toString();

var credentials = {key: privateKey, cert: certificate};

var server = http.createServer(credentials,function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
});

server.listen(8000);

Bu uygulamayı çalıştırdığınızda Ve bu does HTTPS isteklerine cevap. Ben hem ve hala hiçbir es bueno kombinasyonları kullandığım gibi fs sonucu üzerinde toString () önemli olduğunu düşünmüyorum.


EKLE DÜZENLE:

Üretim sistemleri için, muhtemelen nodejs uygulamanıza istekleri proxy yapmak için Nginx veya HAProxy kullanmaktan daha iyi olursunuz. SSL isteklerini işlemek için nginx'i ayarlayabilir ve sadece düğüm uygulamanızla http konuşabilirsiniz. Js.

EKLE DÜZENLE (4/6/2015)

AWS kullanma sistemleri için, SSL Sonlandırmasını işlemek ve EC2 web sunucularınıza düzenli HTTP trafiğine izin vermek için EC2 Elastik Yük Dengeleyicileri kullanmaktan daha iyidir. Daha fazla güvenlik için, güvenlik grubunuzu EC2 bulut sunucularına yalnızca ELB'nin HTTP trafiği göndermesine izin verilecek şekilde ayarlayın, bu da harici şifrelenmemiş HTTP trafiğinin makinelerinize çarpmasını önler.



3
Burada kısaca
cevapladı

AWS ile ilgili son yorum ile ilgili olarak: https modülü ile bir sunucu oluşturulması gerekmiyor mu? Sertifikalarım Jenkins aracılığıyla AWS'ye yüklenir ve ARN ile işlenir; Kullanılacak dosya
yolum

@sqldoug Soruyu anladığımdan emin değilim. AWS ELB'ler HTTPS bağlantılarını kabul edecek ve SSL sonlandırma noktası olarak işlev görecek şekilde yapılandırılabilir. Yani, uygulama sunucularınızla normal HTTP aracılığıyla konuşurlar. Nodejs'lerin SSL ile ilgilenmesinin bir nedeni yoktur, çünkü yalnızca ELB düzeyinde veya HTTP Proxy düzeyinde yığını işleyebilen ekstra işlem yüküdür.
Alan

Teşekkürler Alan; evet O zamandan beri AWS ELB'leri bu şekilde yapılandırılabildiğinde Düğümün SSL ile uğraşmasına gerek olmadığını fark ettim.
sqldoug

Yanıtlar:


672

Express.js'de (sürüm 3'ten beri) bu sözdizimini kullanmalısınız:

var fs = require('fs');
var http = require('http');
var https = require('https');
var privateKey  = fs.readFileSync('sslcert/server.key', 'utf8');
var certificate = fs.readFileSync('sslcert/server.crt', 'utf8');

var credentials = {key: privateKey, cert: certificate};
var express = require('express');
var app = express();

// your express configuration here

var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);

httpServer.listen(8080);
httpsServer.listen(8443);

Bu şekilde yerel http / https sunucusuna hızlı ara katman yazılımı sağlarsınız

Uygulamanızın 1024'ün altındaki bağlantı noktalarında çalışmasını istiyorsanız, sudokomut (önerilmez) veya ters proxy (örn. Nginx, haproxy) kullanmanız gerekir.


2
Hepsi burada yazılmıştır: github.com/visionmedia/express/wiki/Migrating-from-2.x-to-3.x Paragraf Uygulama işlevi
kod adı

74
443'ün HTTPS için varsayılan bağlantı noktası olmasına rağmen, geliştirme sırasında muhtemelen 8443 gibi bir şey kullanmak istediğinizi unutmayın, çünkü çoğu sistem düşük numaralı bağlantı noktalarında kök olmayan dinleyicilere izin vermez.
ebohlman

1
Dostum, sihir gibi çalışıyor :) Yine de olması gerektiği gibi .pem dosyalarını da kabul ediyor
Marcelo Teixeira Ruggeri

5
Express 4 işe yaramaz, işe yarıyor localhost:80ama çalışmıyorhttps://localhost:443
Muhammad Umer

13
ters proxy için nginx kullanacaksanız, düğüm yerine ssl sertifikalarını işleyebilir
Gianfranco P.

48

İlk olarak selfsigned.key ve selfsigned.crt dosyaları oluşturmanız gerekir . Kendinden İmzalı SSL Sertifikası Oluşturma'ya gidin veya aşağıdaki adımları uygulayın.

Terminale gidin ve aşağıdaki komutu çalıştırın.

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./selfsigned.key -out selfsigned.crt

  • Bundan sonra aşağıdaki bilgileri girin
  • Ülke Adı (2 harfli kod) [AU]: ABD
  • Eyalet veya İl Adı (tam ad) [Bazı Eyaletler]: NY
  • Yerellik Adı (ör. Şehir) []: NY
  • Kuruluş Adı (ör. Şirket) [Internet Widgits Pty Ltd]: xyz (Kuruluşunuz)
  • Kuruluş Birimi Adı (ör. Bölüm) []: xyz (Birim Adınız)
  • Ortak Ad (örneğin sunucu FQDN'si veya SİZİN adınız) []: www.xyz.com (URL'niz)
  • E-posta Adresi []: E-postanız

Oluşturulduktan sonra kodunuza anahtar ve sertifika dosyası ekler ve seçenekleri sunucuya iletir.

const express = require('express');
const https = require('https');
const fs = require('fs');
const port = 3000;

var key = fs.readFileSync(__dirname + '/../certs/selfsigned.key');
var cert = fs.readFileSync(__dirname + '/../certs/selfsigned.crt');
var options = {
  key: key,
  cert: cert
};

app = express()
app.get('/', (req, res) => {
   res.send('Now using https..');
});

var server = https.createServer(options, app);

server.listen(port, () => {
  console.log("server starting on port : " + port)
});
  • Son olarak uygulamanızı https kullanarak çalıştırın .

Daha fazla bilgi https://github.com/sagardere/set-up-SSL-in-nodejs


Gerekmedikçe sudo kullanımı önerilmez. Bu işlemi sudo kullanmadan geçtim, ancak makinede yönetici olarak oturum açtım.
jhickok

27

SSL'yi 443 numaralı bağlantı noktasından farklı bir bağlantı noktasında çalıştırarak benzer bir sorunla karşılaştım. Benim durumumda bir paket sertifikası, bir sertifika ve bir anahtar vardı. Paket sertifikası birden çok sertifika içeren bir dosyadır, düğüm bu sertifikaları bir dizinin ayrı öğelerine bölmenizi gerektirir.

    var express = require('express');
    var https = require('https');
    var fs = require('fs');

    var options = {
      ca: [fs.readFileSync(PATH_TO_BUNDLE_CERT_1), fs.readFileSync(PATH_TO_BUNDLE_CERT_2)],
      cert: fs.readFileSync(PATH_TO_CERT),
      key: fs.readFileSync(PATH_TO_KEY)
    };

    app = express()

    app.get('/', function(req,res) {
        res.send('hello');
    });

    var server = https.createServer(options, app);

    server.listen(8001, function(){
        console.log("server running at https://IP_ADDRESS:8001/")
    });

App.js'de https belirtmeniz ve sunucuyu buna göre oluşturmanız gerekir. Ayrıca, kullanmaya çalıştığınız bağlantı noktasının aslında gelen trafiğe izin verdiğinden emin olun.


i bir anahtar ve paketlenmiş bir sertifika var, ben ne cert emin değilim: fs.readFileSync (PATH_TO_CERT), olurdu ve nasıl paketlenmiş sertifika "kırmak", eğer bana sormak eğer sertifikada 20 + anahtarları gibi :)
Muhammad Umar

@MuhammadUmar, paketlenmiş olanı kırmak veya hatta yoksa belirtmek zorunda değilsiniz, eğer varsa, bir paket sertifikanız olacak ve sertifika (genel anahtar) ve anahtar (özel anahtar)
Hayden Thring

@eomoto teşekkürler dostum! bu en iyisi, tamamen ihtiyacım olan örneği çiviledin
Hayden Thring

11

Puanlar dahil:

  1. SSL kurulumu
    1. Config / local.js içinde
    2. Config / env / production.js içinde

HTTP ve WS işleme

  1. Uygulamamızın hatalarını ayıklayabilmemiz için uygulama HTTP üzerinde çalışmalıdır.
  2. Uygulama, güvenlik endişesi için üretimde HTTPS üzerinde çalışmalıdır.
  3. Uygulama üretimi HTTP isteği her zaman https'ye yönlendirilmelidir.

SSL yapılandırması

Sailsjs'de, her şeyi yapılandırmanın iki yolu vardır, birincisi, yapılandırma klasöründe her birinin ayrı dosyaları olduğu şekilde yapılandırmaktır (ayarlarla ilgili veritabanı bağlantısı connections.js içinde bulunur). İkincisi, ortam temel dosya yapısında yapılandırılır, her ortam dosyası config/envklasörde sunulur ve her dosya belirli env için ayarlar içerir.

Sails önce config / env klasörüne bakar ve ardından config / * .js'yi dört gözle bekler

Şimdi ssl kurulumunu yapalım config/local.js.

var local = {
   port: process.env.PORT || 1337,
   environment: process.env.NODE_ENV || 'development'
};

if (process.env.NODE_ENV == 'production') {
    local.ssl = {
        secureProtocol: 'SSLv23_method',
        secureOptions: require('constants').SSL_OP_NO_SSLv3,
        ca: require('fs').readFileSync(__dirname + '/path/to/ca.crt','ascii'),
        key: require('fs').readFileSync(__dirname + '/path/to/jsbot.key','ascii'),
        cert: require('fs').readFileSync(__dirname + '/path/to/jsbot.crt','ascii')
    };
    local.port = 443; // This port should be different than your default port
}

module.exports = local;

Alternatif olarak bunu config / env / production.js dosyasına da ekleyebilirsiniz . (Bu snippet ayrıca birden fazla CARoot certi işleminin nasıl yapılacağını da gösterir)

Veya production.js'de

module.exports = {
    port: 443,
    ssl: {
        secureProtocol: 'SSLv23_method',
        secureOptions: require('constants').SSL_OP_NO_SSLv3,
        ca: [
            require('fs').readFileSync(__dirname + '/path/to/AddTrustExternalCARoot.crt', 'ascii'),
            require('fs').readFileSync(__dirname + '/path/to/COMODORSAAddTrustCA.crt', 'ascii'),
            require('fs').readFileSync(__dirname + '/path/to/COMODORSADomainValidationSecureServerCA.crt', 'ascii')
        ],
        key: require('fs').readFileSync(__dirname + '/path/to/jsbot.key', 'ascii'),
        cert: require('fs').readFileSync(__dirname + '/path/to/jsbot.crt', 'ascii')
    }
};

http / https ve ws / wss yönlendirmesi

Burada ws Web Soketi ve wss Güvenli Web Soketini temsil ediyor, ssl'yi kurduktan sonra şimdi http ve ws her iki istek de güvenli hale geliyor ve sırasıyla https ve wss'e dönüşüyor.

Bizim app herhangi bir blog yazı, sosyal medya yazı gibi istek alacak birçok kaynak var ama sunucumuz sadece https üzerinde çalışır, bu yüzden herhangi bir istek http geldiğinde istemci tarayıcısında "Bu siteye ulaşılamaz" hatası verir. Web sitemizin trafiğini kaybediyoruz. Bu nedenle http isteğini https'ye yönlendirmeliyiz, aynı kurallar websocket için izin verir, aksi takdirde soket başarısız olur.

Bu yüzden aynı sunucuyu 80 numaralı bağlantı noktasında (http) çalıştırmamız ve tüm istekleri 443 numaralı bağlantı noktasına (https) aktarmamız gerekir. Yelkenler, sunucuyu kaldırmadan önce config / bootstrap.js dosyasını derler. Burada ekspres sunucumuzu 80 numaralı bağlantı noktasında başlatabiliriz.

Config / bootstrap.js'de (http sunucusu oluşturun ve tüm istekleri https'ye yönlendirin)

module.exports.bootstrap = function(cb) {
    var express = require("express"),
        app = express();

    app.get('*', function(req, res) {  
        if (req.isSocket) 
            return res.redirect('wss://' + req.headers.host + req.url)  

        return res.redirect('https://' + req.headers.host + req.url)  
    }).listen(80);
    cb();
};

Şimdi http://www.alanadiniz.com adresini ziyaret edebilirsiniz , https://www.alanadiniz.com adresine yönlendirilir


8

Greenlock-express kullanın: Ücretsiz SSL, Otomatik HTTPS

Greenlock , sertifika düzenleme ve yenilemeyi (Let's Encrypt üzerinden) ve http => https yeniden yönlendirmesini, kutudan çıkar çıkmaz yönetir.

express-app.js:

var express = require('express');
var app = express();

app.use('/', function (req, res) {
  res.send({ msg: "Hello, Encrypted World!" })
});

// DO NOT DO app.listen()
// Instead export your app:
module.exports = app;

server.js:

require('greenlock-express').create({
  // Let's Encrypt v2 is ACME draft 11
  version: 'draft-11'
, server: 'https://acme-v02.api.letsencrypt.org/directory'

  // You MUST change these to valid email and domains
, email: 'john.doe@example.com'
, approveDomains: [ 'example.com', 'www.example.com' ]
, agreeTos: true
, configDir: "/path/to/project/acme/"

, app: require('./express-app.j')

, communityMember: true // Get notified of important updates
, telemetry: true       // Contribute telemetry data to the project
}).listen(80, 443);

Ekran yayınlama

QuickStart tanıtımını izleyin: https://youtu.be/e8vaR4CEZ5s

Localhost için

Bu vaktinden önce cevaplamak çünkü yaygın bir takip sorusu:

Localhost'ta SSL sertifikalarınız olamaz. Bununla birlikte, yerel uygulamaları gerçek uygulamalar olarak çalıştırmanıza izin verecek Telebit gibi bir şey kullanabilirsiniz .

Greenlock özel alanlarını, README'de belirtilen çeşitli eklentilerle birlikte DNS-01 zorluklarıyla da kullanabilirsiniz.

Standart Dışı Portlar (yani 80/443 no)

Yukarıdaki localhost ile ilgili notu okuyun - Let's Encrypt ile standart olmayan bağlantı noktalarını kullanamazsınız.

Bununla birlikte, standart olmayan dahili bağlantı noktalarınızı bağlantı noktası iletme, sni-route aracılığıyla harici standart bağlantı noktaları olarak gösterebilir veya sizin için SNI yönlendirmesi ve bağlantı noktası yönlendirme / geçişi yapan Telebit gibi bir şey kullanabilirsiniz.

DNS-01 zorluklarını da kullanabilirsiniz, bu durumda bağlantı noktalarını açığa çıkarmanıza gerek kalmaz ve özel ağlardaki etki alanlarını bu şekilde güvenceye alabilirsiniz.


"Localhost'ta SSL sertifikalarınız olamaz." - Yerel ana bilgisayardaki React uygulamam üzerinde çalışan SSL var. Buraya Express'te nasıl çalışacağını aramak için geldim. Tepki benim ön ucum ve Express benim arka ucum. Stripe için çalışmamın SSL'de olması gerektiğinden, Stripe için çalışması gerekiyor. Açık olmalı, ancak localhost'ta test ediyorum ve sunucuda üretim olacak.
Taersious

Düzeltme: " localhost üzerinde geçerli SSL sertifikalarınız olamaz ".
CoolAJ86

6

Benim için böyle çalışıyor. Kullanılan yönlendirme, tüm normal http'yi de yönlendirecektir.

const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const http = require('http');
const app = express();
var request = require('request');
//For https
const https = require('https');
var fs = require('fs');
var options = {
  key: fs.readFileSync('certificates/private.key'),
  cert: fs.readFileSync('certificates/certificate.crt'),
  ca: fs.readFileSync('certificates/ca_bundle.crt')
};

// API file for interacting with MongoDB
const api = require('./server/routes/api');

// Parsers
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

// Angular DIST output folder
app.use(express.static(path.join(__dirname, 'dist')));

// API location
app.use('/api', api);

// Send all other requests to the Angular app
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist/index.html'));
});
app.use(function(req,resp,next){
  if (req.headers['x-forwarded-proto'] == 'http') {
      return resp.redirect(301, 'https://' + req.headers.host + '/');
  } else {
      return next();
  }
});


http.createServer(app).listen(80)
https.createServer(options, app).listen(443);

0

Bu benim ekspres 4.0 için çalışma kodum .

ekspres 4.0, 3.0 ve diğerlerinden çok farklıdır.

4.0 burada https ekleyeceğiniz / bin / www dosyanız var.

"npm start", express 4.0 sunucusunu başlatmanın standart yoludur.

readFileSync () işlevi __dirname get current dizinini kullanmalıdır

while () kullan .// geçerli dizine bakın.

Önce private.key ve public.cert dosyasını / bin klasörün altına koyarsınız, WWW dosyasıyla aynı klasördür .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.