Включение HTTPS на express.Яш

Я пытаюсь заставить HTTPS работать на express.js для узла, и я не могу понять это.

Это мой app.js код.

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);

когда я запускаю его, он, похоже, отвечает только на HTTP-запросы.

Я написал простой ванили node.js на основе HTTPS приложение:

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 Worldn');
});

server.listen(8000);

и когда я запускаю это приложение, это тут отвечать на запросы HTTPS. Обратите внимание, что я не думаю, что toString () на результат fs имеет значение, поскольку я использовал комбинации обоих и по-прежнему нет es bueno.


ИЗМЕНИТЬ, ЧТОБЫ ДОБАВИТЬ:

для производственных систем вам, вероятно, лучше использовать Nginx или HAProxy для прокси-запросов к вашему приложению nodejs. Вы можете настроить nginx для обработки запросов ssl и просто говорить http с вашим приложением узла.js.

ИЗМЕНИТЬ, ЧТОБЫ ДОБАВИТЬ (4/6/2015)

для систем, использующих AWS, лучше использовать эластичные балансировщики нагрузки EC2 для обработки SSL-завершения и разрешить регулярный HTTP-трафик на веб-серверы EC2. Для кроме того, настройте свою группу безопасности так, чтобы только ELB разрешал отправлять HTTP-трафик экземплярам EC2, что предотвратит попадание внешнего незашифрованного HTTP-трафика на ваши машины.


7 ответов


В Express.js (начиная с версии 3) Вы должны использовать этот синтаксис:

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);

таким образом, вы предоставляете промежуточное ПО express для собственного сервера http/https

Если вы хотите, чтобы ваше приложение работало на портах ниже 1024, вам нужно будет использовать sudo команда (не рекомендуется) или использовать обратный прокси (например, nginx, haproxy).


я столкнулся с аналогичной проблемой с получением SSL для работы на порту, отличном от порта 443. В моем случае у меня был сертификат пакета, а также сертификат и ключ. Сертификат пакета-это файл, содержащий несколько сертификатов, узел требует разбить эти сертификаты на отдельные элементы массива.

    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/")
    });

в приложение.js вам нужно указать https и создать сервер соответственно. Кроме того, убедитесь, что порт, который вы пытаетесь использовать, фактически разрешает входящий трафик.


В Том Числе:

  1. настройка SSL
    1. в config / local.js
    2. в config/env / production.js

обработка HTTP и WS

  1. приложение должно работать на HTTP в разработке, чтобы мы могли легко отлаживать наши приложение.
  2. приложение должно работать на HTTPS в производстве для обеспечения безопасности.
  3. App production HTTP-запрос всегда должен перенаправляться на протокол https.

настройки SSL

в Sailsjs есть два способа настроить все вещи, во-первых, настроить в папке config, у каждого из которых есть свои отдельные файлы (например, соединение с базой данных относительно настроек лежит в соединениях.в JS ). И во-вторых, настроить на основе файловой структуры среды, каждый файл среды представлен в config/env папка и каждый файл содержит настройки для конкретного env.

паруса сначала заглядывает папка config/ env, а затем с нетерпением ждем config/*.js

теперь позволяет настроить ssl в 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;

альтернативы вы можете добавить это в config/env / production.js тоже. (Этот фрагмент также показывает, как обрабатывать несколько сертификатов CARoot)

или производства.js

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 и WS/ВСС перенаправление

здесь ws является веб Сокет и wss представляют собой безопасный веб-сокет, так как мы настроили ssl, то теперь http и WS оба запроса становятся безопасными и преобразуются в https и wss соответственно.

есть много источников из нашего приложения будет получать запрос, как любой пост в блоге, социальных медиа, но наш сервер работает только на https, поэтому, когда любой запрос приходит от http, он дает" этот сайт не может быть достигнут " ошибка в клиентском браузере. И мы теряем трафик нашего сайта. Поэтому мы должны перенаправить http-запрос на https, те же правила позволяют websocket в противном случае сокет не удастся.

поэтому нам нужно запустить тот же сервер на порту 80 (http) и перенаправить весь запрос на порт 443(https). Паруса сначала компилируют config / bootstrap.файл js перед поднятием сервера. Здесь мы можем запустить наш экспресс-сервер на порту 80.

в config / bootstrap.js (создайте http-сервер и перенаправьте все запросы на https)

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();
};

теперь вы можете посетить http://www.yourdomain.com, оно будет перенаправить наhttps://www.yourdomain.com


вот как это работает для меня. Используемое перенаправление также перенаправит все обычные http.

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);

используйте greenlock-express: бесплатный SSL, автоматический HTTPS

Greenlock обрабатывает выдачу и обновление сертификата (через Let's Encrypt) и HTTP => перенаправление https, из коробки.

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);

видеоуроки

смотрите демонстрацию QuickStart:https://youtu.be/e8vaR4CEZ5s

для Имя localhost

просто отвечая на это заранее, потому что это общий последующий вопрос:

вы не можете иметь SSL-сертификаты на localhost. Однако, вы можете использовать что-то вроде Telebit, который позволит вам запускать локальные приложения, как реальные.

вы также можете использовать частные домены с Greenlock через DNS-01 challenges, который упоминается в README вместе с различными плагинами, которые его поддерживают.

нестандартные порты (т. е. нет 80 / 443)

прочитайте Примечание выше о localhost - вы не можете использовать нестандартные порты с Let's Encrypt либо.

однако вы можете выставить свои внутренние нестандартные порты как внешние стандартные порты через port-forward, sni-route или использовать что-то вроде Telebit, который выполняет SNI-маршрутизацию и переадресацию / ретрансляцию портов для вас.

вы также можете использовать вызовы DNS-01, в этом случае вам не нужно будет выставлять порты вообще, и вы также можете защитить домены в частных сетях именно такой образ.


Это мой код на экспресс 4.0.

express 4.0 сильно отличается от 3.0 и других.

4.0 у вас есть файл /bin/www, который вы собираетесь добавить https здесь.

" npm start " - это стандартный способ запуска сервера express 4.0.

функция readFileSync () должна использовать _ _ dirname получить текущий каталог

в то время как требуют() использовать ./ см. текущий каталог.

сначала вы ставите частный.ключ и открытый.файл сертификата в папку /bin , Это та же папка, что и WWW file.


сначала перейдите в создайте Самозаверяющий сертификат SSL

  • терминал и выполнить следующую команду.

судо OpenSSL требуе -x509-на-узлы -365 дней-newkey и RSA:2048 -keyout ./самоподписанных.самоподписанный ключ.crt

  • и поставить следующую информацию
  • название страны (2-буквенный код) [AU]:нас
  • название штата или провинции (полное имя) [Some-State]: Нью-Йорк
  • название местности (например, город) []:Нью-Йорк
  • название организации (например, компания) [Internet Widgits Pty Ltd]:xyz (ваша организация)
  • имя организационной единицы (например, раздел) []: xyz (имя вашего устройства)
  • общее имя (например, FQDN сервера или ваше имя) []: www.xyz.com (Ваш URL)
  • Адрес Электронной Почты []: ваш электронная почта

после создания добавьте файл key & cert в свой код, мой файл bin/www как.

     var app = require('../app'); 
    var debug = require('debug')('driftApp:server');
    //var http = require('http');
    var http = require('https');
    var fs = require('fs');

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

    var port = normalizePort(process.env.PORT || '3000');
    app.set('port', port);
    console.log("Server Started On Port: ", port);
    //var server = http.createServer(app);
    var server = http.createServer(options, app);
    server.listen(port);
    server.on('error', onError);
    server.on('listening', onListening);
    function normalizePort(val) {
    var port = parseInt(val, 10);

    if (isNaN(port)) {
     // named pipe
     return val;
    }
    if (port >= 0) {
     // port number
     return port;
    }
    return false;
    }
    function onError(error) {
    if (error.syscall !== 'listen') {
     throw error;
    }
    var bind = typeof port === 'string' ?
     'Pipe ' + port :
     'Port ' + port;
    // handle specific listen errors with friendly messages
    switch (error.code) {
     case 'EACCES':
        console.error(bind + ' requires elevated privileges');
        process.exit(1);
        break;
     case 'EADDRINUSE':
        console.error(bind + ' is already in use');
        process.exit(1);
        break;
     default:
        throw error;
      }
     }
    function onListening() {
    var addr = server.address();
    var bind = typeof addr === 'string' ?
     'pipe ' + addr :
     'port ' + addr.port;
     debug('Listening on ' + bind);
    }
  • наконец запустите приложение с помощью https