NodeJS ssl for subdomain - node.js

I have a site, for example test.com, I need to make a copy of the same site with the address subdomain.test.com and change a couple of files on this subdomain for my purposes. The problem is that the categories of the site use NodeJS, and now running 9 NodeJS. Each server has registered SSL certificates of the following type (the settings are the same for everyone):
var fs = require('fs');
var sslOptions = {
key: fs.readFileSync('/etc/letsencrypt/live/test.com/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/test.com/fullchain.pem'),
requestCert: true,
rejectUnauthorized: false
};
var https = require('https'),
server = https.createServer(sslOptions, app),
io = require('socket.io')(server),
I made a subdomain for example subdomain.test.com, but when I visit the site, the console swears at the following error: ERR_CERT_COMMON_NAME_INVALID.
As I understand it, an error occurs because the certificate was issued for test.com, and I'm trying to use it additionally on subdomain.test.com. What can be done in this situation? Either in the NodeJS servers themselves when SSL certificates are connected, duplicate the settings by adding, for example, the number 1, or are there any other options?

Related

SocketIO throws net::ERR_CERT_AUTHORITY_INVALID on self signed certificate

I am using socket io on client:
const socket = require('socket.io-client')('https://localhost:4200', {secure: true, rejectUnauthorized: false})
And on server:
let https = require('https')
let fs = require('fs')
let options = {
key: fs.readFileSync('cert/my.net.key'),
cert: fs.readFileSync('cert/my.net.cert'),
requestCert: false,
rejectUnauthorized: false,
};
const server = https.createServer(options, require('express')())
const io = require('socket.io')(server)
All services are started normally, but on client I am getting polling-xhr.js:263 GET https://localhost:4200/socket.io/?EIO=3&transport=polling&t=MPa6ZuL net::ERR_CERT_AUTHORITY_INVALID
Why? Whats is wrong?
Browsers don't like self-signed certificates for security reasons.
To get around this in your development environment, I see three options:
Use a certificate issued by a certification unit.
It could be something free, like https://letsencrypt.org/.
Create your server dynamically, based on the development environment, not to include certificates and work directly with HTTP and WS (and not HTTPS and WSS).
Change the configuration of your browser used in development so that it accepts self-signed certificates.
For Chrome, for example, just enable the Allow invalid certificates for resources loaded from localhost. (chrome://flags/#allow-insecure-localhost) setting.
But remember that you will not be able to use self-signed certificates in production environments.

assign HTTPS to node.js socket.io

i want to create HTTPS server to my node.js socket.io server,
did it with self sign certification, using this code
var fs = require( 'fs' );
var app = require('express')();
var https = require('https');
var server = https.createServer({
key: fs.readFileSync('C:/ssl/ia.key'),
cert: fs.readFileSync('C:/ssl/ia.crt'),
requestCert: false,
rejectUnauthorized: false
},app);
server.listen(8888);
but when purchasing real one i only get .crt file, how to secure my node app using it on windows server?
Short answer: no private key - no way.
You need a private key that was used to purchase the certificate.
Or you can use letsencrypt-express:
Free SSL and managed or automatic HTTPS for node.js with Express, Koa,
Connect, Hapi, and all other middleware systems.
https://www.npmjs.com/package/letsencrypt-express
Found the answer, i had to do a CSR from my server using OPENSSL batch, in that case it will create CSR and the private KEY, buying SSL using the CSR will give me the CRT
and i will use the generated key from the OPENSSL.

Self signed cert NodeJS rejectUnauthorized

I created a structure certificates to authenticate client-> server, allowing only certificates recognized by the CA using this step by step: https://jamielinux.com/docs/openssl-certificate-authority/create-the-root-pair.html
I checked the authority with openssl, and it returns to me OK the certificate server and client, with the same CA. But by setting the parameter rejectUnauthorized to true on the server, the client can not connect.
Is there any extra parameter should I set up to allow authentication by a certificate that I generated?
---- Edit
On the client side I get the following error: ""ECONNRESET" socket hang up"
I spent a long time digging into a similar issue, and I wrote up this to talk about how to dig into various OpenSSL issues with node.js: http://www.thedreaming.org/2016/09/27/nodejs-ssl/
The short answer, though, is if you need to pass the ca parameter when creating you client connection. If you have the self-signed certificate stored in cert.pem, then the client code looks something like:
var https = require('https');
var fs = require('fs');
var certificate = fs.readFileSync('cert.pem');
var options = {
host: serverHost,
port: 443,
path: '/',
ca: [certificate]
};
https.request(options, function(res) {
res.pipe(process.stdout);
}).end();

how do i correctly proxy https requests to another https server for cordova

I have a number of different servers running on my system, all of them running a secure connection on there own port, etc. 50001,50002,50003...
all of thees can be accessed directly from https://domain1.com:50001 ...
now, not only do I want to limit the number of ports, but also change the domain so etc.
https://domain1.com:50001 <- https://srv1.domain2.com:443
https://domain1.com:50002 <- https://srv2.domain2.com:443
https://domain1.com:50003 <- https://srv3.domain2.com:443
All of thees servers run separate nodejs instances.
Now I want to build a proxy than redirect this, and I have chosen nodejs since everything else we do is in nodejs.
what i have now:
var app = require('express')();
var options = {
key : fs.readFileSync(CONFIG.sslKey).toString(),
cert : fs.readFileSync(CONFIG.sslCertificate).toString(),
ca : fs.readFileSync(CONFIG.sslCA).toString()
};
var http = require('https').Server(options,app);
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({
ssl: {
key : fs.readFileSync(CONFIGsecure.sslKey).toString(),
cert : fs.readFileSync(CONFIGsecure.sslCertificate).toString(),
ca : fs.readFileSync(CONFIGsecure.sslCA).toString()
},
secure: true
});
var handleRequests = function(req, res){
proxyTo = "https://domain1.com:50001"; <= some logic chooses this based on req.headers.host
proxy.web(req, res, { target: proxyTo });
};
app.get('/*', handleRequests );
app.post('/*', handleRequests );
app.put('/*', handleRequests );
app.delete('/*', handleRequests );
http.listen(443, function(){});
okay so this actually works very well, everything is going where it should go in a browser, and in a cordova app using jquery ajax everything also works very well.
however if i use
FileTransfer().download(...)
I get error code 3 (connection error).
If I connect directly to https://domain1.com:50001 (direct) the app works, but if i connect to https://srv1.domain2.com:443 (the proxy) the app does not work.
All the certificates are valid, wildcard certificate on *.domain2.com and single certificate on domain1.com.
The end servers has domain1.com certificate installed and the proxy has *.domain2.com wildcard certificate installed.
Any idea on how to correctly setup a proxy server? The system is windows server 2012 R2 and I am open to use a real proxy if needed. However it would be nice with a solution as simple as possible.
I have tried example two form here:
http://blog.nodejitsu.com/http-proxy-intro/
however this is the same problem, and it is only GET requests.
I have also tried disabling https on the end server so thats it's only the proxy that is secure, however, same result...
Thanks...
Okay so i found the issue, for some reason req.headers.host string also contained the :port, and i was only switching on the address. now everything works perfekt.

how to configure https in sails.js

I am trying to setup a local HTTPS server for testing in Sails.js? I am not able to find any pointer how to do that in sails.js? For express,
var express = require('express');
var https = require('https');
var http = require('http');
var fs = require('fs');
// This line is from the Node.js HTTPS documentation.
var options = {
key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};
// Create a service (the app object is just a callback).
var app = express();
// Create an HTTP service.
http.createServer(app).listen(80);
// Create an HTTPS service identical to the HTTP service.
https.createServer(options, app).listen(443);
Any idea about sails.js?
For sails.js version 0.10, include this in config/locals.js (if locals.js does not exist, create it):
var fs = require('fs');
module.exports = {
ssl : {
key: fs.readFileSync('path-to-key.key'),
cert: fs.readFileSync('path-to-crt.crt')
}
};
Source: https://stackoverflow.com/a/28565113/2459071
If you're using the latest v0.9 (and maybe some versions of v0.8) take look inside of config/bootstrap.js. You should be able to access your express app via the sails.express context. From there I think you should be able to do with it what you want to...
Also someone in the #sailsjs irc channel said this worked for them
module.exports.bootstrap = function (cb) {
var fs = require('fs');
sails.config.express.serverOptions = {
key: fs.readFileSync('ssl/key.pem'),
cert: fs.readFileSync('ssl/cert.pem')
};
cb();
};
Maybe it's just me but I could get either of the above working for sails v0.9.7, but I did get it working by editing the config/local.js file like so;
var fs = require('fs');
module.exports = {
port: process.env.PORT || 1337,
environment: process.env.NODE_ENV || 'development',
express: { serverOptions : {
key: fs.readFileSync('ssl/key.pem'),
cert: fs.readFileSync('ssl/cert.pem')
}
}
};
Now I'm not saying this is the 'correct' way to do this, however it works for me!
Shameless self promotion
More about this on my blog!
End shameless self promotion :D
This contribution enhances the solution for to support native mobile applications and old browsers.
This solution worked really well for me when when just using a modern web browser to access my SSL site. However when I attempted to make requests using the AFNetworking library it did not recognise the SSL certificate. This was due to the iPhone application requiring the intermediate SSL certificates (sometimes called the ca bundle).
You can add the intermediate certificate in using the following code.
express: {
serverOptions : {
key: fs.readFileSync('ssl/key.pem'),
cert: fs.readFileSync('ssl/cert.pem'),
ca: fs.readFileSync('ssl/intermediate.pem')
}
}
When creating you intermediate certificate (which can normally be downloaded from your SSL certificate provider) it is important to get the order of certificates right.
This linux command really helped with debugging.
openssl s_client -connect yoursite.com:443 -showcerts
The above does not work for sails v0.9.3. I ended up with the following workaround. (require fs first of course)
express : {serverOptions : {
key: fs.readFileSync('ssl/server-key.pem'),
cert: fs.readFileSync('ssl/server-cert.pem'),
}}
I have also faced this kind of issues in my production sails app (v0.11.x and v0.12.x). Android release version apk is not able to connect to sails app and some old version browsers do not accept SSL certificate with web app.
I got some intermediate certificate error like below
The certificate is not trusted in all web browsers. You may need to install an Intermediate/chain certificate to link it to a trusted root certificate.
Finally, I found a solution
ssl: {
ca: require('fs').readFileSync('ssl/intermediate.crt', 'utf8').toString(),
key: require('fs').readFileSync('ssl/example_com.key', 'utf8').toString(),
cert: require('fs').readFileSync('ssl/main.crt', 'utf8').toString()
}
I hope this will help someone.

Resources