Ativando HTTPS em express.js

Estou tentando fazer com que o HTTPS funcione no express.js para nó, e não consigo descobrir.

Este é o meu código 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); 

Quando o executo, parece responder apenas a solicitações HTTP.

Eu escrevi o aplicativo HTTPS baseado no node.js simples do vanilla:

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

E quando eu executo este aplicativo, ele responde a solicitações HTTPS. Note que eu não acho que o toString () no resultado fs é importante, já que usei combinações de ambos e ainda não há bueno.


EDITAR PARA ADICIONAR:

Para sistemas de produção, provavelmente é melhor usar o Nginx ou o HAProxy para fazer solicitações de proxy ao aplicativo nodejs. Você pode configurar o nginx para manipular as solicitações ssl e apenas falar http no seu nó app.js.

EDITAR PARA ADICIONAR (4/6/2015)

Para sistemas que usam o AWS, é melhor usar EC2 Elastic Load Balancers para manipular a Terminação SSL e permitir o tráfego HTTP regular para os servidores da Web EC2. Para obter mais segurança, configure seu grupo de segurança de forma que somente o ELB possa enviar tráfego HTTP para as instâncias do EC2, o que impedirá que o tráfego HTTP externo não criptografado atinja suas máquinas.


   

Em express.js (desde a versão 3) você deve usar essa syntax:

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

Dessa forma, você fornece middleware expresso ao servidor nativo http / https

Se você quiser que seu aplicativo seja executado em portas abaixo de 1024, você precisará usar o comando sudo (não recomendado) ou usar um proxy reverso (por exemplo, nginx, haproxy).

Eu me deparei com um problema semelhante com a obtenção de SSL para trabalhar em uma porta diferente da porta 443. No meu caso eu tinha um certificado de pacote, bem como um certificado e uma chave. O certificado do pacote configurável é um arquivo que contém vários certificados. O nó exige que você os separe em elementos separados de uma matriz.

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

Em app.js, você precisa especificar https e criar o servidor de acordo. Além disso, certifique-se de que a porta que você está tentando usar esteja realmente permitindo o tráfego de input.

É assim que funciona para mim. O redirecionamento usado também redirectá todo o http normal.

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

Incluindo Pontos:

  1. Configuração SSL
    1. Em config / local.js
    2. Em config / env / production.js

Manipulação de HTTP e WS

  1. O aplicativo deve ser executado no HTTP em desenvolvimento para que possamos depurar facilmente nosso aplicativo.
  2. O aplicativo deve ser executado em HTTPS em produção por questões de segurança.
  3. A solicitação HTTP de produção de aplicativos deve sempre redirect para https.

Configuração SSL

No Sailsjs existem duas maneiras de configurar todas as coisas, primeiro é configurar na pasta de configuração, cada uma com seus arquivos separados (como a conexão do database com as configurações está dentro de connections.js). E segundo é configurar na estrutura do arquivo base do ambiente, cada arquivo de ambiente apresenta na pasta config/env e cada arquivo contém configurações para env particular.

Velas primeiro procura na pasta config / env e, em seguida, olhar para a frente para config / * .js

Agora vamos configurar o ssl em 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; 

Alternativa você pode adicionar isso em config / env / production.js também. (Este trecho também mostra como lidar com vários certificados CARoot)

Ou em production.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') } }; 

redirecionamento http / https & ws / wss

Aqui está o Web Socket e o wss representa o Secure Web Socket, já que configuramos o ssl e agora o http e ws os dois pedidos se tornam seguros e se transformam em https e wss respectivamente.

Há muitas fonts de nosso aplicativo que receberão solicitações como qualquer postagem de blog, post de mídia social, mas nosso servidor é executado somente em https, portanto, quando qualquer solicitação vier de http, o erro “Este site não pode ser acessado” é exibido no navegador do cliente. E nós perdemos o tráfego do nosso site. Portanto, devemos redirect a solicitação http para https, as mesmas regras permitem o websocket. Caso contrário, o soquete falhará.

Portanto, precisamos executar o mesmo servidor na porta 80 (http) e desviar todas as solicitações para a porta 443 (https). Navega primeiro compilar o arquivo config / bootstrap.js antes de levantar o servidor. Aqui podemos iniciar nosso servidor expresso na porta 80.

Em config / bootstrap.js (crie um servidor http e redirecione todos os pedidos para 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(); }; 

Agora você pode visitar http://www.yourdomain.com , ele irá redirect para https://www.yourdomain.com

Use o greenlock-express: SSL grátis, HTTPS automatizado

A Greenlock cuida da emissão e renovação de certificados (via Let’s Encrypt) e http => https redirection, fora da checkbox.

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

Screencast

Veja a demonstração QuickStart: https://youtu.be/e8vaR4CEZ5s

Para Localhost

Apenas respondendo a isso antes, porque é uma pergunta comum:

Você não pode ter certificados SSL no host local. No entanto, você pode usar algo como o Telebit, que permitirá que você execute aplicativos locais como reais.

Você também pode usar domínios privados com Greenlock via DNS-01 desafios, que é mencionado no README junto com vários plugins que o suportam.

Portas não padronizadas (isto é, sem 80/443)

Leia a nota acima sobre localhost – você não pode usar portas não padrão com o Let’s Encrypt.

No entanto, você pode expor suas portas internas não-padrão como portas padrão externas via porta-direta, sni-route ou usar algo como o Telebit que faz o SNI-routing e o port-forwarding / relaying para você.

Você também pode usar os desafios do DNS-01, caso em que você não precisará expor as portas e também poderá proteger os domínios em redes privadas dessa maneira.

Este é o meu código de trabalho para o expresso 4.0 .

O express 4.0 é muito diferente do 3.0 e outros.

4.0 você tem / bin / www arquivo, que você vai adicionar https aqui.

“npm start” é a maneira padrão de iniciar o servidor do Express 4.0.

function readFileSync () deve usar __dirname get diretório atual

while require () use ./ consulte o diretório atual.

Primeiro você coloca o arquivo private.key e public.cert na pasta / bin. É a mesma pasta que o arquivo WWW .

Primeiro, vá para Criar um certificado SSL autoassinado

  • Vá para o terminal e execute o seguinte comando.

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

  • E coloque a seguinte informação
  • Nome do país (código de 2 letras) [AU]: EUA
  • Nome do Estado ou Província (nome completo) [Algum Estado]: NY
  • Nome da localidade (por exemplo, cidade) []: NY
  • Nome da organização (por exemplo, empresa) [Internet Widgits Pty Ltd]: xyz (sua – Organização)
  • Nome da Unidade Organizacional (por exemplo, seção) []: xyz (nome da sua unidade)
  • Nome comum (por exemplo, servidor FQDN ou seu nome) []: http://www.xyz.com (sua URL)
  • Endereço de Email []: seu email

Após a criação, adicione o arquivo key & cert em seu código, como o arquivo My 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); } 
  • Finalmente, execute seu aplicativo usando https