When I run the code like below on Node.JS v0.10.36 - server responds on https request, but then I run the same code on Node.JS v4.2.1 - server doesn't respond at all,however in that time browser does not "say" that anything goes wrong - it just continues to load the page. Should I rewrite the code in some way?
var express = require('express');
var https = require('https');
//var http = require('http');
var fs = require('fs');
var crypto=require('crypto')
var app = express();
var ssl_conf=require(__dirname+'/config/ssl.json');
var secureContext = {}
try{
for(var domain in ssl_conf){
secureContext[domain]=getSecureContext(ssl_conf[domain].domain);
}
}
catch(err){
console.log('error with ssl.config file '+err);
}
function getSecureContext (domain) {//returns secure context
return crypto.createCredentials({
key: fs.readFileSync('./ssl/'+domain+'.key'),
cert: fs.readFileSync('./ssl/'+domain+'.crt')
}).context;
}
var options = {
SNICallback: function (domain) {
return secureContext[domain];
},
//in case SNI is not available use this cert
cert: fs.readFileSync('./ssl/2_helena.softpro.ua.crt'),
key: fs.readFileSync('./ssl/2_helena.softpro.ua.key')
}
app.get('/',function(req,res){//simple route
res.send("your domain is "+req.hostname);
})
https.createServer(options, app).listen(443,function(){//run server
console.log('https server running on 443')
});
In recent version 12.0.0 + next code is ok
var options = {
SNICallback:function(domain,cb){
var ctx= tls.createSecureContext(
secureContext[domain]//{key:<Buffer>,cert:<Buffer>}
).context
if(cb)
cb(null,ctx)
else
return ctx;
}
}
Related
How can I run two app.js within hhtps.createServer() on given condition?
Or you can say two completely different node website within one http.createServer().
Below code is running only html files with on some modification.
Such as folder name with correspond to website folder. For https you can create your certificate, otherwise use http.createServer instead https.createServer.
enter code hereconst path = require("path");
const fs = require('fs');
const http = require('http');
const https = require('https');
const { Server } = require("socket.io");
const static = require('node-static');
const app1 = require('./folder1/app');
const app2 = require('./folder2/app');
let folder1 = new (static.Server)('./folder1');
let folder2 = new (static.Server)('./folder2');
//Some certificate
const options = {
key: fs.readFileSync(path.join(__dirname, './Cert') + '/folder1.com.key', 'utf8'),
cert: fs.readFileSync(path.join(__dirname, './Cert') + '/folder_com.crt', 'utf8')
};
let server = https.createServer(options,(req, res) => {
req.addListener('end', () => {
try {
let hostName = req.headers.host.split(':')[0];
console.log(hostName);
switch(hostName){
case 'folder1.com':
folder1.serve(req, res);
break;
case 'folder2.com':
folder2.serve(req, res)
break;
default:
folder2.serve(req, res)
}
}
catch{
console.log(e);
}
}).resume();
})
const io = new Server(server, {log: false});
let port = process.env.PORT || 443;
server.listen(port);
console.log('Server is listening on port: '+ port);
Are you trying to expose both an http and an https endpoint?
If so, my suggestion would be to only expose https and handle incoming http requests in your webserver such as nginx and have them redirect to https automatically.
I am trying to put some extra headers on the responses sent by a https server created with Express. For example, I want to set a X-Frame-Options response header.
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('../certificate/ca.key'),
cert: fs.readFileSync('../certificate/ca.crt')
};
module.exports = https.createServer(options, app).listen(port, function (err) {
if (err)
return console.log(err);
var uri = 'https://localhost:' + port;
opn(uri);
});
I tried various things, but none of them worked. Did anybody manage to do such thing?
I managed to use Helmet in order to set the headers I needed.
I am using nginx with my ssl certificates and it's giving me the https version of my site which is great. The problem is my socket.io communications don't work unless i use a regular http connection. I apologize if this is a bit long, but i'm not sure what i'm doing here and wanted to make sure you guys had everything you might need to know. I have tried the solutions of various different sites some of which were on here, but none of them worked.
I tried manually creating the https server instead of letting express do it but that resulted in nothing loading at all, with the current implementation i can at least see the site.
upstream project {
server example.org:4000;
}
server {
listen 80;
return https://$host$request_uri;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_certificate /home/adam/SSL/public.crt;
ssl_certificate_key /home/adam/SSL/example.org.key;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://example.org;
}
}
That seems to be working as when i go to my site, it automatically takes me to the https version and the page is loaded. The issue is when is when the client side tries to connect i keep getting:
"https://MY_SERVER_IP:4040/socket.io/?EIO=3&transport=polling&t=M0CPjUDnet::ERR_CONNECTION_CLOSED"
printed to the console
Here's my client and server code:
var IPaddress = 'https://MY_SERVER_IP:4040';
var socket = io.connect(IPaddress,{secure:true});
socket.on('connect', function (socket) {
console.log('Connected!');
});
server code:
var express = require('express');
var app = express();
var privateKey = fs.readFileSync(__dirname+'/SSL/example.com.key','utf8');
var certificate = fs.readFileSync(__dirname+'/SSL/public.crt','utf8');
var intermediate = fs.readFileSync(__dirname+'/SSL/intermediate.crt','utf8');
var options = {key:privateKey,cert:certificate,ca:intermediate};
var io = require('socket.io').listen(4040,options);
//var io = require('socket.io').listen(4040);
io.sockets.on('connection', function (socket) {
socket.on('disconnect',function(){
console.log("A client has left us :(");
});
});
app.listen(4000);
Update - 02/12/2017
In my code i have this line:
require('./routes.js')(app);
which contains:
module.exports = function(app) {
app.get('/main',function(req,res){
if (req.session.user == null){
// if user is not logged-in redirect back to login page //
res.redirect('/');
} else{
res.sendFile(path.join(__dirname + '/FrontEnd/main.html'));
}
});
// viewed at http://localhost:8080
app.get('/', function(req, res) {
if(req.cookies.user == undefined || req.cookies.pass == undefined){
res.sendFile(path.join(__dirname + '/FrontEnd/login.html'));
}else {
//attempt automatic login
AM.autoLogin(req.cookies.user,req.cookies.pass,function(o){
if(o !=null){
req.session.user = o;
res.sendFile(path.join(__dirname + '/FrontEnd/home.html'));
}else{
res.sendFile(path.join(__dirname + '/FrontEnd/login.html'));
}
});
}
});
......
Could this be causing the 502 bad gateway error?
Expanding on my comment, in your current server code, both express and socket.io are only accepting regular HTTP connections. The socket.io listen(port[, options]) function does not accept HTTPS connections.
You started on the right approach with manually creating an HTTPS server. You then need to attach express and socket.io to that server.
var fs = require('fs');
var express = require('express');
var app = express();
var privateKey = fs.readFileSync(__dirname + '/SSL/example.com.key', 'utf8');
var certificate = fs.readFileSync(__dirname + '/SSL/public.crt', 'utf8');
var intermediate = fs.readFileSync(__dirname+'/SSL/intermediate.crt', 'utf8');
var options = { key: privateKey, cert: certificate, ca: intermediate };
// Create our HTTPS server here and attach express to it
var server = require('https').createServer(options, app);
// Attach socket.io to our existing HTTPS server
var io = require('socket.io')(server);
io.sockets.on('connection', function (socket) {
socket.on('disconnect', function() {
console.log("A client has left us :(");
});
});
server.listen(4000);
I'd like to encrypt my Koa server with SSL. It seems simple enough with a regular httpServer, but I'm not how to do it with Koa. Could anyone help?
I stumbled upon this. Launching an https server with the node package and passing it the Koa server instance .callback() does the trick.
Koa's doc
var fs = require('fs');
var path = require('path');
var http = require('http');
var https = require('https');
var Koa = require('koa');
var server = new Koa();
// add main routes
// the following routes are for the authorisation challenges
// ... we'll come back to this shortly
var acmeRouter = require('./acme-router.js');
server
.use(acmeRouter.routes())
.use(acmeRouter.allowedMethods());
var config = {
domain: 'example.com',
http: {
port: 8989,
},
https: {
port: 7979,
options: {
key: fs.readFileSync(path.resolve(process.cwd(), 'certs/privkey.pem'), 'utf8').toString(),
cert: fs.readFileSync(path.resolve(process.cwd(), 'certs/fullchain.pem'), 'utf8').toString(),
},
},
};
let serverCallback = server.callback();
try {
var httpServer = http.createServer(serverCallback);
httpServer
.listen(config.http.port, function(err) {
if (!!err) {
console.error('HTTP server FAIL: ', err, (err && err.stack));
}
else {
console.log(`HTTP server OK: http://${config.domain}:${config.http.port}`);
}
});
}
catch (ex) {
console.error('Failed to start HTTP server\n', ex, (ex && ex.stack));
}
try {
var httpsServer = https.createServer(config.https.options, serverCallback);
httpsServer
.listen(config.https.port, function(err) {
if (!!err) {
console.error('HTTPS server FAIL: ', err, (err && err.stack));
}
else {
console.log(`HTTPS server OK: http://${config.domain}:${config.https.port}`);
}
});
}
catch (ex) {
console.error('Failed to start HTTPS server\n', ex, (ex && ex.stack));
}
module.exports = server;
Looks like there's no clear cut way to do this, but running Nginx on top of my server was an easy workaround.
I want to create an https server with express 4.x. Even if a lot of code found on google is based on express 3.x I think I made the port correctly.
Even if I tried to goole it is not very clear to me how to generate the keys. Without the key I'm expecting 401.
I tried with the script found in this gist. But I'm keeping on receiving the error Error: DEPTH_ZERO_SELF_SIGNED_CERT.
I'd like to test it both with curl, request, and super test.
This is what actually I have:
server.js
var express = require('express')
, https = require('https')
, fs = require('fs');
var privateKey = fs.readFileSync('./server/server-private-key.pem').toString();
var certificate = fs.readFileSync('./server/server-certificate.pem').toString();
var options = {
key : privateKey
, cert : certificate
}
var app = express();
app.get('/', function(req, res) {
req.client.authorized ?
res.json({"status":"approved"}) :
res.json({"status":"denied"}, 401);
});
server = https.createServer(options,app);
var port = 12345;
server.listen(port, function(){
console.log("Express server listening on port " + port);
});
client.js
var https = require('https');
var fs = require('fs');
var options = {
host: 'localhost',
port: 12345,
method: 'GET',
path: '/',
key: fs.readFileSync('./client/client-private-key.pem'),
cert: fs.readFileSync('./client/client-certificate.pem'),
headers: {}
};
var req = https.request(options, function(res) {
console.log('dudee');
console.log(res);
});
req.end();
With cURL you can use the -k flag to bypass the self-signed cert problem.
With request you can just set rejectUnauthorized: false in the request options.