Can Host Headers resolved to a virtual host node.js like in Apache? - node.js

Host headers cause a webserver to return a different virtual host based on which DNS name the DNS server resolved to send the browser to the servers ip. Is it possible to build this sort of functionality into a node.js http server between multiple deployed apps?
(Of course you could just use Apache to do this, but can it be done without Apache?)

Yes, you can certainly implement this same behavior in node. The http module only provides a basic server instance with a request callback, but you can expand on that by checking the Host header and then routing the request to the proper application.
If you are using an server framework like express or connect, there is a vhost middleware that will provide this functionality.

Related

Can we make our own web server to host a websites and respond to HTTP requests?

A web server responds to an HTTP request and sends the client a set of HTML, CSS, and JS files.
After we build a website or a web application, we usually have to host it on a well-known web server like IIS or Apache to make it accessible all around the world (on the internet).
Can't we just make our own web server so that it can responds to all incoming HTTP requests that the client sends to our computer without having to use IIS?
As wazz and Lex says, you could build your own server to listen the special port and handle the request based on your requirement, but it contains performance and security issue.
If you still want to build it by yourself. I suggest you could refer to some existing server like KestrelHttpServer.

Setting up internal web server with Node.js

I want to host a web app with node.js on a Linux virtual machine using the the HTTP module.
As the app will be visualising sensitive data I want to ensure it can only be accessed from PCs on the same LAN.
My understanding is that using the HTTP module a web server is created that's initially only accessible by other PCs on the same LAN. I've seen that either by tunnelling or portforwarding a node.js server can be exposed if desired.
Question
Are there any other important considerations/ways the server could be accessed externally?
Is there a particular way I can setup a node.js server to be confident that it's only accessible to local traffic?
It really depends what you are protecting against.
For example, somebody on your LAN could port forward your service using something like ngrok. There are a few things you can check for:
In this case the header x-forwarded-for is set. So, to protect against this you can check for this header on the incoming request, and if set you can reject the request.
The host header is also set and will indicate how the client referred to your service - if it is as you expect (maybe a direct local LAN address such as 192.168.0.xxx:3000) then all is OK, if not (I ran ngrok on a local service and got something of the form xxxxxxxx.ngrok.io) then reject it.
Of course a malicious somebody could create their own server to redirect requests. The only way there is to put in usernames and passwords or similar. At least you then known who is (allegedly) accessing your service and do something about it.
However, if you are not trying to pretect against a malicious internal actor, then you should be good as you are - I can't think of any way (unless there is a security hole in your LAN) for your service to be made public without somebody actively setting that up.
My last suggestion would be to use something like express rather than the http module by itself. It really does make life a lot simpler. I use it a lot for just this kind of simple internal server.
Thought I'd add a quick example. I've tested this with ngrok and it blocks access via the public address but works find via localhost. Change the host test to whatever local address (or addresses) you want to serve this service from.
const express=require('express');
const app=express();
app.use((req,res,next)=>{
if (req.headers.host!=='localhost:3000' || req.headers['x-forwarded-for']){
res.status(403).send('Invalid access!');
} else next();
});
app.get('/',(req,res)=>res.send('Hello World!'));
app.listen(3000,()=>{
console.log('Service started. Try it at http://localhost:3000/');
});
I would prefer using nginx as a proxy here and rely on nginx' configuration to accept traffic from local LAN to the node.js web server. If this is not possible, a local firewall would be the best tool for the job.

AWS Loadbalancer Proxy for Nodejs

I have configured the load balancer to route the request to two of Ec2 Instance running a NodeJs server. I need to direct the request coming from both http (port 80) and https (port 443) to http (port 80) of the EC2 instances in NodeJs. I have uploaded the ssl certificate to AWS and configured the load balancer to use ssl certificate. The problem is the request coming from http port doesn't automatically route to https. It has to be a server side script or snipped which I need to write in server.js which should be routing the http to https, i tried to do it and it run into endless redirection. So questions -
Is there any guide to do this from AWS ?
If not then how one can achieve this, any pointers or suggestions would be greatly appreciated.
On the server side you can check the X-Forwarded-Proto
(original request protocol) and if it's heaving value http you can send redirect (http 302) to a url with https protocol..
though with ALB (application load balancer you may specify a set of rules, maybe it's possible to do that there..)
I couldn't find a guide from AWS, but I will keep searching and update the answer in the case I find it.
Usually, when you write applications in Node.js, you specify which port should your app run at. It means that you will need two different servers listening. And when your app receives a request on port 80 (HTTP), it should redirect to your HTTPS server, like in this answer.
Another point that may be relevant to your question is that, in production environments, you don't usually bind a port to your Node.js server, since it's not production ready. You probably want to use a reverse proxy and load balancer like Nginx or HAProxy.
If you are using the AWS ALB (Application Load Balancer) they announced the http->https redirect today. Take a look: https://exampleloadbalancer.com/redirect_demo.html
Put your ELB behind the Cloudfront and in settings of your distribution select forward HTTP to HTTPS.
The following doc will be helpful
https://docs.aws.amazon.com/waf/latest/developerguide/tutorials-ddos-cross-service-ELB.html
This method has two benefit:
1-Your problem will be solve
2-You can use the benefit of the powerful CDN, for more information about Cloudfront read https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html
Update:
You can forward traffic from HTTP to HTTPS by edit your Listeners setting in your ELB.

NodeJS http module vs Nginx Server

I have read that proxies can be created by Nginx server for nodejs application to listen on but I am doubtful as to what exactly this will serve additional purpose and advantages compared to http module provide by nodejs for listening purpose.
For one, you can serve multiple Node applications on one server, with host based virtual servers managed by nginx, so that requests to the same port but with different Host: HTTP header reach different Node applications.
Also nginx can be set up to serve static assets without hitting your Node app and do some caching if you need it.
Those are two things that you can achieve with adding nginx to the mix but you may not need that in your case. Also, you can run a reverse proxy with Node and without nginx if that's what you prefer.

Connecting to Node.js server from a website?

So say, you have:
A VPS running a Node.js server
A web host & domain that's running a website say www.example.com
Is there a way you can have www.example.com connect to the Node.js server and retrieve data from it?
Because I just started messing around with node, and I've looked at over 10 tutorials and read a bunch of implementations of Node.js and in all of their examples they say connect to localhost:8080 or 127.0.0.1:8080. (That would mean my vps would have to host www.example.com (the client) & the node.js (the server) for me to use both??)
But I haven't come across any code/tutorials that allows me to run a JavaScript script to connect to the Node.js server and load in data dynamically from the page I'm at. Thanks.
Here's an example of code I'm looking at. http://tympanus.net/codrops/2012/10/11/real-time-geolocation-service-with-node-js/
Yes, you can use any URL to reach a nodeJs server.
Routing a request (to say www.example.com) to a nodeJs server has nothing to do with the nodeJs server. You have to make sure that the routing rules are in place, but that is completely separate to your server.
Update in response to you comment clarification:
Are you trying to make connections:
client -> example.com -> node.js?
If so, and example.com is a standard server, then yes, just make calls to node.js URL, that'll work fine
If you looking for the below flow
node.js
client/
\
example.com
And if you client is a browser, then you will have to deal with cross-domain issues as discussed here AJAX cross domain call

Resources