Designing real-time web application (Node.js and socket.io) - node.js

I want to ask about some good practices. I have a Node.js (Express) web server and socket.io push server (in case technology matters). I can turn both of them into one application but I want them separated (they can communicate with each other if necessary). There are two reasons to do that:
It will be easier to manage, debug and develop the app;
It will be a lot easier to scale the app. I can just add another instance of push server or web server if necessary;
This is at least what I believe. The only problem is that when a client connects to the seperate socket.io server then it won't send cookies (different port, cross-domain policy).
The workaround I came up with is to put a reverse proxy (written in Node.js as well) in front and check what kind of request we are dealing with and send it to web server or push server accordingly. Great, now we have cookies in both web server and push server. The reverse proxy can be a load balancer which is an additional bonus.
It looks like a good idea to me. What do you think about this design? Perhaps any other workaround for cookie problem?

I recently did something simular, we initially used a node.js reverse proxy but ran into reliability/scalability problems. We found serving static files and proxying requests was best left to nginx. haproxy is also a very viable solution for stand alone proxying as well.
HaProxy
Nginix as a reverse proxy

Related

Why use nginx if there is a proxy middleware for nodejs?

I'm really confused with reverse proxy. What i understood is in forward proxy the client know the destination server but the server doesn't know the client, in reverse proxy the server knows the client but the client doesn't know the "server" he's visiting is a actually proxying to some other server. And to use the reverse proxy you can use NGINX. But if we can use that, why do express framework middlewares like http-proxy-middleware
exist?
and if my understanding of proxy and reverse proxy is wrong please correct me
Lets take an abstract example:
You will agree that you must be using port 3000 or something to run NodeJS... Right?
And lets say you also use angular/react or html+css to run your frontend website which is lets say on port 4200 (default for angular).
Now what if you want to have only one server and want two different services (frontend in angular and backend in nodejs) to run on that single server only.
So you need something in between your client and server to distinguish between the requests whether to forward them to angular or nodejs or any other service as well that is running on the same server.
What reverse proxy such as NGINX will do is you will define some rules on the basis of which the administrator of the server can utilize same server to serve various services.
This is the simplest example I can think of on the top of my head.

Is it safe to open the Nodejs server port to the world?

A React app and Nodejs server which is used to retrieve and manipulate the data are running on the same server. When accessing the app locally it workes fine, but when accessed externally the app is visible but without data. The reason behind this is that the port on which the application is running is open but the port on which the Nodejs server is running is not.
My question is this, what is the best way to solve this issue? The simplest solution would be to open up the other port, but I am assuming that is not the most secure solution.
Any suggestions would be appreciated.
Open to port for the outside world and implement a token-based request verification system.
You can implement CSRF token verification. It always checks that request comes from a trusted source only.
Do this using a reverse proxy server, like nginx, to listen to the open https port. The reverse proxy will handle the https encryption, rather than burdening your nodejs code with it. nginx is multithreaded and can do https efficiently.
The reverse proxy passes along requests to your http://localhost:3000 nodejs. In my experience, this arrangement works very well at large scale.
Explaining how to do this is too much for a stack overflow answer. But you'll find plenty of online advice.

NGINX, THe Edge, HAPRoxy

I was going through Uber Engineering website where I came across this paragraph and I it confused me a lot, if anyone can make it clear for me then I would be thankful to him/her:
The Edge The frontline API for our mobile apps consists of over 600
stateless endpoints that join together multiple services. It routes
incoming requests from our mobile clients to other APIs or services.
It’s all written in Node.js, except at the edge, where our NGINX front
end does SSL termination and some authentication. The NGINX front end
also proxies to our frontline API through an HAProxy load balancer.
This is the link.
NGINX is already a reverse proxy + load balancer, then from where HAProxy load balancer came in the picture and where exactly it fits in the picture? What is "the edge" he talked about? Either the guy who wrote his he wrote confused words or I dont know English.
Please help.
It seems like they're using HAProxy strictly as a load balancer, and using NGINX strictly to terminate SSL and for authentication. It isn't necessary in most cases to use HAProxy along with NGINX, as you mentioned, NGINX has load-balancing capabilities, but being Uber, they probably ran into some unique problems that required the use of both. According to the information I've read, such as http://www.loadbalancer.org/blog/nginx-vs-haproxy/ and https://thehftguy.com/2016/10/03/haproxy-vs-nginx-why-you-should-never-use-nginx-for-load-balancing/, NGINX works extremely well as a web server, including the use case where it is serving as a reverse proxy for a node application, but its load-balancing capabilities are basic and not nearly as performant as HAProxy. Additionally, HAProxy exposes many more metrics for monitoring, and has more advanced routing capabilities.
Load balancing is not the core feature of NGINX. In the context of a node.js application, usually what you would see NGINX used for is to serve as a reverse proxy, meaning that NGINX is the web server, and http requests come through it. Then, based on the hostname and other rules, it forwards on the HTTP request to whatever port your node.js application is running on. As part of this flow, often NGINX will handle SSL termination, so that this computationally-intensive task is not being handled by node.js. Additionally, NGINX is often used to serve static assets for node.js apps, as it is more efficient, especially when compressing assets.

Is HTTPS behind reverse proxy needed?

I have an API server running behind an nginx reverse proxy. It is important to have all requests to my API server be secured via TLS since it handles sensitive data.
I've setup nginx to work with TLS (LetsEncrypt) so that seems to be okay. However, requests from nginx to my API server are still insecure http requests (this is all happening across docker containers, by the way).
Is it a best practice to also setup https between the reverse proxy and the API server? If so, how would I go about doing that without over-engineering it?
It all comes down to how secure or paranoid you'd like your implementation to be. It may also depend on the type of data you're playing with. For instance: I'd definitely do this for credit card numbers or other sensitive information.
As the comments have already stated, you would typically terminate SSL connections at the front facing webserver, assuming the API backend is also inside your LAN, which you trust and control. If you want to go that extra mile, you could also set up SSL on the API backend. Details of how to do that depend on the software you're using on your backend.
If you do decide to implement SSL on the API backend, the setup would be similar to what you did to setup Nginx with SSL on the frontend, with the main difference being you don't need to use a public certificate on the backend. It can be self-signed, since no one else besides your web server will be talking to it. Then it's just a matter of fixing all the URIs in your code to use HTTPS.

Where to terminate SSL/TLS in Node & Nginx

I'm building a web application using the MEAN stack. The site contains authentication (using passport.js) so I would like to secure our connection with SSL/TLS.
For our deployment we're using nginx as a reverse proxy to the Node app running on the same AWS EC2 instance.
My question is: With my setup, what is the best practice way to setup an https (SSL/TLS) connection? Should I get a certificate and set it up at the nginx layer? Should I do it in my node app directly? Is there some other better way?
I've done some googling but haven't found anything profound. If anyone could point me to an article on the topic that would be very useful as well.
Thanks in advance!
First it's good to have SSL running on NGINX. So the communication is encrypted for the visitor in the first place (at least to the NGINX). If you're running Node on the same instance it's probably not absolutely necessary to encrypt also the traffic between Node and NGINX. But as soon as you have NGINX on another place running you should use SSL on Node too. As the data could potentially be accessed by Hackers.

Resources