Solución:
Ryan, gracias por señalarme en la dirección correcta. Completé tu respuesta (segundo párrafo) un poco con algo de código y funciona. En este escenario, estos fragmentos de código se colocan en mi aplicación express:
// set up plain http server
var http = express();
// set up a route to redirect http to https
http.get('*', function(req, res) {
res.redirect('https://' + req.headers.host + req.url);
// Or, if you don't want to automatically detect the domain name from the request header, you can hard code it:
// res.redirect('https://example.com' + req.url);
})
// have it listen on 8080
http.listen(8080);
El servidor https express escucha ATM en 3000. Configuré estas reglas de iptables para que el nodo no tenga que ejecutarse como root:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 3000
En conjunto, esto funciona exactamente como yo quería.
Para evitar el robo de cookies a través de HTTP, vea esta respuesta (de los comentarios) o use este código:
const session = require('cookie-session');
app.use(
session({
secret: "some secret",
httpOnly: true, // Don't let browser javascript access cookies.
secure: true, // Only use cookies over https.
})
);
Gracias a este chico: https://www.tonyerwin.com/2014/09/redirecting-http-to-https-with-nodejs.html
app.use (function (req, res, next) {
if (req.secure) {
// request was via https, so do no special handling
next();
} else {
// request was via http, so redirect to https
res.redirect('https://' + req.headers.host + req.url);
}
});
Si sigue los puertos convencionales, ya que HTTP intenta el puerto 80 de forma predeterminada y HTTPS intenta el puerto 443 de forma predeterminada, simplemente puede tener dos servidores en la misma máquina: Aquí está el código:
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('./key.pem'),
cert: fs.readFileSync('./cert.pem')
};
https.createServer(options, function (req, res) {
res.end('secure!');
}).listen(443);
// Redirect from http port 80 to https
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(301, { "Location": "https://" + req.headers['host'] + req.url });
res.end();
}).listen(80);
Prueba con https:
$ curl https://127.0.0.1 -k
secure!
Con http:
$ curl http://127.0.0.1 -i
HTTP/1.1 301 Moved Permanently
Location: https://127.0.0.1/
Date: Sun, 01 Jun 2014 06:15:16 GMT
Connection: keep-alive
Transfer-Encoding: chunked
Más detalles: Nodejs HTTP y HTTPS en el mismo puerto