Use Reverse Proxy from Https client to Http server running locally on my machine - node.js

I have a published site that uses HTTPS. The site needs to communicates with a HTTP node Express API. The API is run on my local machine. Everything worked fine until I switched the client application to use HTTPS. Now I receive mixed content warnings. I have been reading about reverse proxys and wonder if this could be the solution to my problem. Is it possible to proxy a request to my localhost? Or will localhost point to the server the proxy is on?
I have been looking at using nginx as the reverse proxy server but I have zero experience with proxys and not positive how to go about it.
I am mainly wondering if it is possible or not before I dig any deeper.

Yes, this is a pretty standard use case for using nginx (or any other reverse proxy). You would configure the location prefixes, etc that need to go to your backend application and proxy (via proxy_pass directive) to them. Any static content can be served directly from nginx. All of this can then behind nginx.
Assuming that your application is never issuing absolute urls which make use of "http://" this should resolve your mixed content warnings.
You will probably want to read some tutorials but the basics of your configuration would be:
server {
listen 443 ssl; # you can also add http2
server_name hostnames that you listen for;
ssl_certificate_key /path/to/cert.key;
ssl_certificate /path/to/cert.pem;
root /var/www/sites/foo.com;
location /path/handled/by/application {
proxy_pass http://localhost:8000; # or whatever port is
}
}

Related

How to handle Nginx reverse proxy 502 Error in specific case?

Here is my nginx default
server {
listen 80;
listen [::]:80;
server_name _;
location /login-with-args.html {
alias /opt/code-server/login-with-args.html;
}
}
And I am having login-with-args.html at this /opt/code-server/login-with-args.html location but the curl command in linux is giving me 200 but in my browser is it showing me 502 error.
this is what the url I am hitting from UI
https://url/login-with-args.html?password=1233&Id=12123&Code=sand-42&port=8127
Generally I could have advised you to enable error logging and check the corresponding log.
But as far as I see, there are mismatches in your question. Your configuration contains listen 80; which, in generally, means plain HTTP, except if you're add ssl parameter (anyway I'd not recommend you to enable SSL/TLS on port 80). But URL you try to request is:
https://url/login-with-args.html?password=1233&Id=12123&Code=sand-42&port=8127
which assumes using HTTPS on port 443 (by default, if not specified other).
At the same time there is no reverse proxy defined in your configuration. You just aliased static file.
Since you got 502 error, you nginx is either located behind some proxy (or CDN) or have another server section, containing listen with ssl parameter and reverse proxy definition somewhere in configuration.

Cloudflare - No further requests possible during download

My site allows users to download big .zip files. A problem I'm dealing with right now is that whenever the user is currently downloading such a file, all other requests to the site wait until the download is finished or cancelled, making the site practically unusable. In the Chrome network tab, the request shows as pending. Why could this be?
The server itself is implemented in Node.js using Express and is proxied through NGINX and then through Cloudflare. When I connect to the Express server or the NGINX proxy directly, this problem doesn't come up, only when it's routed through Cloudflare from what I have observed.
This is my NGINX config, if of any help:
server {
listen 80;
listen [::]:80;
server_name marbleland.vani.ga;
client_max_body_size 20m;
location / {
proxy_pass "http://localhost:20020/";
}
}
Am I missing something obvious?

Where do I put my Node JS app so it is accessible via the main website?

I've recently installed a nodejs app (keystone) app in my home/myusername/myappname directory.
When I visit www.mydomain.com, nothing displays - even after turning on my nodejs app.
Where should these files be?
I am running ubuntu 16.04.
In the past I have worked with a var/www folder, but I am not using apache - do I need to manually create this folder?
Thanks!
For your app to be visible it has to be running (obviously) and accessible on port 80 (if you want it to be available without adding a port number to the URL).
It doesn't matter where it is on the disk as long as it's running.
You don't need Apache or nginx or any other server. Your Node app may listen on port 80. But alternatively it can listen on some other port and your other server (Apache, nginx, etc.) can proxy the requests to that port.
But if your app is listening on, e.g. port 3000 then you should be able to access it as http://www.example.com:3000/.
Also, make sure that your domain is configured correctly. It's A record for IPv4 (or AAAA for IPv6) of the www subdomain should be equal to the publicly accessible IP address of your server.
And make sure that the port you use is not blocked by the firewall.
Update
To see how you can set the port with Keystone, see:
http://keystonejs.com/docs/configuration/#options-server
It can be either changed in the config or you can run your app with:
PORT=80 node yourApp.js
instead of:
node yourApp.js
but keep in mind that to use the port number below 1024 you will usually need the program to run as root (or add a special privilege which is more complicated).
It will also mean that this will be the only application that you can run on this server, even if you have more domain names.
If you don't want to run as root or you want to host more application, it is easiest to install nginx and proxy the requests. Such a configuration is called a "reverse proxy" - it's good to search for info and tutorials using that phrase.
The simplest nginx config would be something like this:
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://localhost:3000;
}
}
You can set it in:
/etc/nginx/sites-available/default
or in a different file as e.g.:
/etc/nginx/sites-available/example
and then symlinked as /etc/nginx/sites-enabled/example
You need to restart nginx after changing the config.
You can find more options on configuring reverse proxies here:
https://www.nginx.com/resources/admin-guide/reverse-proxy/
You need to make a proxy between Apache and your Node.js application because Node.js has a built-in server. Supose your Node.js app is served on 9000 port. Then you need to make a proxy to redirect all trafic in 80 port to 9000 port where the Node.js app is running.
1. Enable mod_proxy
You can do this through a2enmond.
sudo a2enmod proxy
sudo a2enmod proxy_http
2. Set the proxy
Edit the /etc/apache2/sites-available/example.com.conf file and add the following lines:
ProxyRequests Off
Order deny, allow from All
ProxyPass / http://0.0.0.0:9000 ProxyPassReverse / http://0.0.0.0:9000
This basically say: "Redirect all traffic from root / to http://0.0.0.0:9000. The host 0.0.0.0:9000 is where your app is running.
Finally restart apache to enable changes.

node.js application running on a port should have no port visible in the URL bar

I have 5 domains pointing to the same machine, let's say these domains are:
example1.com
example2.com
example3.com
example4.com
example5.com
My server has a virtual host file managed by apache, which controls these 5 domains.
I have a node.js app running on port 3000.
If I connect to any of the 5 domains, and type :3000 at the end, I can see the node.js app splash screen.
For example, if I connect to example1.com:3000 it serves me the same page (the node.js app) that can be reached by connecting to example2.com:3000 and example3.com:3000, etc. I understand why this is happening.
However, I am trying to edit my configuration such that the following criteria are met:
Users can only connect to the node app when they type in example5.com, and not any of the other domains.
Users do not have to type in the port number, example5.com:3000, when trying to reach the node app.
I have searched and found some information which leads me to believe this is normally achieved by setting up a reverse proxy, but most examples I find are using nginx or node. It would be nice to figure out a reverse proxy solution with apache so I don't have to re-write all my virtual host logic with node or nginx.
You need to set up a reverse proxy. An easy way to do this is to use nginx. Install and start nginx and in your config file put the following:
server {
listen 80;
server_name example1.com;
location / {
proxy_pass http://localhost:3000;
}
}
And then run your node server on port 3000.

Deploying multiple nodeJS on Digitalocean with Dokku

I've tried to deploy two nodeJS apps on Digitalocean using a dokku droplet. I am using the "virtualhost naming" scheme but there is a problem.
My DNS configuration looks like this:
I have the main app and the admin app. I would expect to view the admin app when i visit app.example.com (I actually have a proper domain name) but I can see the same app when hitting example.com and app.example.com.
There is something wrong with nginx probably, but I don't know exactly what is going bad?
One thing I have noticed is that whichever app is installed first will be the one that example.com forwards to.
You are correct to attribute this behaviour to Nginx. I think it's due to it falling back to this config somehow when it doesn't detect a config for example.com
This dokku plugin (https://github.com/progrium/dokku/tree/master/plugins/nginx-vhosts) is responsible for rewriting the nginx.conf for each app every time it is deployed.
Nowadays it uses a template nginx.conf (https://github.com/progrium/dokku/blob/master/plugins/nginx-vhosts/templates/nginx.conf) although this is a fairly recent change so be sure your on a recent version.
You will end up with a Nginx config that looks like the following:
server {
listen [::]:80;
listen 80;
server_name app.example.com;
return 301 https://$host$request_uri;
}
I'm not currently sure why the above snippet results in the described behaviour. A work around is to setup your own nginx conf in /etc/nginx/sites-enabled/ with
server_name example.com;
but pointing to a holding page or whatever works for you.

Resources