Node JS https hosted on bluehost - node.js

I have a dedicated VPS through bluehost, hosted on it is my node.js project. As of now I can use app.listen(80) so that anyone who navigates to my url will get my ejs to correctly display to them, however the web browser shows the "not secure" message to the left of the url. I'm trying to get https working so that a web hook can send data to my web server. The other program that sends the web hook data requires an https address not http. I know that bluehost has built in SSL but I'm not sure how to use this in tandem with a node.js app. It seems to work fine if I publish just a simple HTML page. I've tried creating a self-signed certificate with openssl and using the following code
const options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
};
https.createServer(options, function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
But chrome refuses to accept the certificate when I navigate too mydomain.com:8000, additionally I'd prefer to find out how to set it up so that mydomain.com defaults to https, not http like it is doing so now. Thanks in advance for any advice!

Ended up finding that the BlueHost autoSSL files are stored at /home//ssl/ and you can read in both the *.key and *.cert files from there. The file paths don't change when the cert renews and it's signed by a proper CA instead of self signed so chrome and other browsers will actually accept it! Hope this helps someone else

Related

http-server doesnt serve up any files

So im trying to make my localhost server up https to do some testing with webhooks, i was looking into http-server and i can get the https server up and running, but it wont server any content for my MERN application, it simply just downloads the file from the browser. I need to be able to server up my application from the localhost over https, but it seems that http-server only creates a web server... im sure if i was serving static content this might work, but it doesnt.
does anyone have any idea how to proceed? the goal is to ensure i can setup an https://localhost:3000 that i will expose on my router so i can take in content from a different API via a webhook and see what the data looks like.
Yes, setting up a https server can be done easily.
var privateKey = fs.readFileSync( 'privatekey.pem' );
var certificate = fs.readFileSync( 'certificate.pem' );
https.createServer({
key: privateKey,
cert: certificate
}, app).listen(port);
See the Node docs for more info: https://nodejs.org/api/https.html
Then you need to use a router to serve the application logic.

Unable to implement HTTPS on nodeJS server

I'm currently doing a login portal with ReactJS frontend and NodeJS backend, deployed on an AWS EC2 instance. I have used certbot to obtain an SSL, and nginx is able to serve the /build from the ReactJS app. Now my website is accessible at https://my-website without any errors.
When it sends API (https://my-website:8080/api) calls to my server (intialized using PM2), it returns a net::ERR_CERT_AUTHORITY_INVALID. My server is using corsOptions with options: https://my-website.
Is there a specific term or practice I should be doing?
What I've Tried
Use certbot to generate a server.key and a server.pem, and use the https package to create a server with them, but it returns net::ERR_CERT_AUTHORITY_INVALID.
Used fs to open the credentials created for my frontend app, but it returns a permission denied.
I've read that it is not ideal to directly manipulate credentials on the backend, and something along the lines of a reverse proxy should be adopted, however, I am still clueless after reading and trying out. I'd appreciate any help to get this going! Thanks in advance!
My Fix
I simply used the credentials I obtained from certbot in my server.js. Here's a snippet:
const credentials = {
key: myKey.pem,
cert: myCert.pem,
ca: myCa.pem
}
https.createServer(credentials, app).listen(PORT)
The main thing is to switch to the root user (sudo su), else access will be denied to open the file. Hope this helps!

Always redirect http traffic to https traffic in google app engine nodejs flex environment [duplicate]

I've followed the answer of this: Redirect from http to https in google cloud but it does not seem to be currently accurate any more. The anchor referenced ( https://cloud.google.com/appengine/docs/flexible/nodejs/configuring-your-app-with-app-yaml#security ) seems to have been removed but without a note of a replacement.
For reference, I am serving NodeJS over a Google App (flex) Engine. As per the answer I've got in my app.yaml:
handlers:
- url: /.*
script: IGNORED
secure: always
Since HTTPS is obviously terminated before it hits my Express engine (and redirection on there would be useless); how is it currently correctly implemented?
Potentially helpful, I have an external domain attached via the "Custom domains" tab in the console, and there is indeed a SSL certificate configured (so if a user manually goes to https://.com everything is fine)
The flexible environment does not current support handlers in the app.yaml. If you want https:// redirection, you have a few options:
Use helmet to do to HSTS stuff for you, and implement your own initial redirect.
I wrote a happy little library to always forces SSL on all routes for express yes-https
We are considering auto-redirecting all traffic to SSL by default. Do you think that would be a good thing for your apps?
Pulling Justin's yes-https library, I was able to get this to work:
var app = express();
app.use(function(req, res, next){
if (req.host != 'localhost' && req.get('X-Forwarded-Proto') == 'http') {
res.redirect(`https://${req.host}${req.url}`);
return;
}
app.router(req, res, next);
});
At first I thought I had to do that since I was on an appengine subdomain and couldn't use HSTS. Then I learned HSTS works fine for subdomains. :) Regardless, I thought people might want to see what the magic bit to use was if they didn't want to use yes-https for some reason.
Justin, auto-redirecting all traffic to SSL by default sounds great to me. I just spent hours trying to figure out how to do so before I found this post because I was trying to get my app to get Chrome's add to homescreen install banner as per https://developers.google.com/web/fundamentals/engage-and-retain/app-install-banners/.
GCP This should be as easy to just use the gcloud app cli and configure a header (Strict-Transport-Security) or redirect rule. Perhaps the push is to force us to Firebase Hosting instead which is forcing HTTPS already. For a quick solution for Single Page apps (static content) with React, Angular etc, we can use this JS snippet.
It ignores localhost environments. You can change localhost with a host name that you would like to exclude. It then redirects using https as protocol.
if ( location.host.indexOf("localhost") < 0 && location.protocol.toLowerCase() !== "https:"){
const url= `https://${location.host}`;
location.replace(url);
}

angular universal https problems

I have an angular universal app set up. I do POST requests on the server-side using localhost to pre-render my app and this works fine.
An example working url would be http://localhost:8000/api/get-info.
I've now put the app into production on an external url (apache server). I'm also using ssl.
Now when I try to do a POST request on the server-side to pre-render my app, I get back a response with status: 0, url: null (I'm assuming this means the connection was refused).
An example non-working url would be https://mywebsite.com/api/get-info.
What really stumps me is that when the app loads on the client, all HTTPS requests start working. So the problem is I cannot get the express server to send POST requests to my external url.
I've tested a post request on the server-side to a different website (twitter), and that seems to work fine as well. So i'm not entirely sure where I've gone wrong.
I already have CORS set to '*' as well.
Try using
http://localhost:8000/api/get-info
in production as well. Since your Angular app is rendered on the same server as your API is running, using localhost should just work fine. It doesn't matter if you are on an external URL.
I do something similar (its a GET but that shouldn't matter) with my translations:
if ( this.isServer ) {
translateLoader.setUrl( 'http://localhost:4000/assets/localization/' );
} else {
translateLoader.setUrl( 'assets/localization/' );
}
It works locally and in production (both server and client).
I just encountered this problem myself for two days. Please take a look at my comment on https://github.com/angular/universal/issues/856#issuecomment-426254727.
Basically what I did was I did a conditional check in Angular to see if the APP is running in browser or in server (rendered by Angular Universal), and change my API endpoint to actual IP in https or localhost in http accordingly. Also in my Nginx setting, I only redirect incoming request from browser to https by checking if the server_name is localhost.
Hope it helps!

HTTP to HTTPS redirection on App Engine Flexible

I've followed the answer of this: Redirect from http to https in google cloud but it does not seem to be currently accurate any more. The anchor referenced ( https://cloud.google.com/appengine/docs/flexible/nodejs/configuring-your-app-with-app-yaml#security ) seems to have been removed but without a note of a replacement.
For reference, I am serving NodeJS over a Google App (flex) Engine. As per the answer I've got in my app.yaml:
handlers:
- url: /.*
script: IGNORED
secure: always
Since HTTPS is obviously terminated before it hits my Express engine (and redirection on there would be useless); how is it currently correctly implemented?
Potentially helpful, I have an external domain attached via the "Custom domains" tab in the console, and there is indeed a SSL certificate configured (so if a user manually goes to https://.com everything is fine)
The flexible environment does not current support handlers in the app.yaml. If you want https:// redirection, you have a few options:
Use helmet to do to HSTS stuff for you, and implement your own initial redirect.
I wrote a happy little library to always forces SSL on all routes for express yes-https
We are considering auto-redirecting all traffic to SSL by default. Do you think that would be a good thing for your apps?
Pulling Justin's yes-https library, I was able to get this to work:
var app = express();
app.use(function(req, res, next){
if (req.host != 'localhost' && req.get('X-Forwarded-Proto') == 'http') {
res.redirect(`https://${req.host}${req.url}`);
return;
}
app.router(req, res, next);
});
At first I thought I had to do that since I was on an appengine subdomain and couldn't use HSTS. Then I learned HSTS works fine for subdomains. :) Regardless, I thought people might want to see what the magic bit to use was if they didn't want to use yes-https for some reason.
Justin, auto-redirecting all traffic to SSL by default sounds great to me. I just spent hours trying to figure out how to do so before I found this post because I was trying to get my app to get Chrome's add to homescreen install banner as per https://developers.google.com/web/fundamentals/engage-and-retain/app-install-banners/.
GCP This should be as easy to just use the gcloud app cli and configure a header (Strict-Transport-Security) or redirect rule. Perhaps the push is to force us to Firebase Hosting instead which is forcing HTTPS already. For a quick solution for Single Page apps (static content) with React, Angular etc, we can use this JS snippet.
It ignores localhost environments. You can change localhost with a host name that you would like to exclude. It then redirects using https as protocol.
if ( location.host.indexOf("localhost") < 0 && location.protocol.toLowerCase() !== "https:"){
const url= `https://${location.host}`;
location.replace(url);
}

Resources