Assign Remote MongoDB ip to a Domain Name - javascript

I have installed mongoDB in GCP virtual machine. I am using apache reverse proxy to forward my domain 'example.com' to mongoDB port http://localhost:27017.
When I try to connect my remote db using:
mongo -u admin -p admin example.com it does not work. But when I try connect my remote db using:
mongo -u admin -p admin remote_ip:27017 it works. How can I make the domain part working. Here is my Apache .conf file:
<VirtualHost *:80>
ServerName example.com
<Proxy balancer://mycluster>
BalancerMember http://127.0.0.1:27017
</Proxy>
ProxyPreserveHost On
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
</VirtualHost>

You made an HTTP proxy. Mongo shell attempts to create a persistent TCP connection, which your proxy doesn't know how to deal with.
I'm not sure if Apache even can do this. It's really just meant to pass on http requests. I do know nginx can do it. Here is more info on how:
https://docs.nginx.com/nginx/admin-guide/load-balancer/tcp-udp-load-balancer/

Related

Node.js doesn't serve page on proxy pass from apache

I've found similar questions on Stack and other forums but no working answers.
I have a node.js chat server running on port 3000 of my local machine, and an Apache server running on port 80. They both work as expected: browsing to localhost gives me Apache, and localhost:3000 gives me the node app. However, when I set up a ProxyPass directive to make the nodejs app accessible from localhost/node, like this...
<VirtualHost *:80>
ProxyPreserveHost On
ProxyRequests Off
ServerName localhost
ProxyPass /node http://localhost:3000/
ProxyPassReverse /node http://localhost:3000/
</VirtualHost>
... the page loads, but the server isn't processing the page. It renders, but node doesn't work.
Notably, the following configuration allows me to access the node server on port 80 for all traffic, but isn't what I want to achieve.
<VirtualHost *:80>
ProxyPreserveHost On
ProxyRequests Off
ServerName localhost
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
</VirtualHost>

How do I get nodejs to run without a port number on a Apache server

I have a nodejs api application running inside a codeigniter environment. Im trying to access the nodejs api's without using a port number in the url
currently you can only hit the node api at
http://wrl.xx.com:8010/api
And I would like to have it accessible through a url like :
http://wrl.xx.com/api/
I tried to run a reverse proxy with no success
<VirtualHost *:80>
ServerName wrl.xx.com
ProxyRequests off
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
ProxyPass / http://localhost:8010/
ProxyPassReverse / http://localhost:8010/
ProxyPreserveHost on
</VirtualHost>
Assuming you intend to differentiate requests looking for the nodejs app from requests seeking the codigniter app by seeing /api as the root path, try:
ProxyPass /api http://localhost:8010/api
ProxyPassReverse /api http://localhost:8010/api
See ProxyPass and ProxyPassReverse for more magic.
Disclaimer: I have no experience with codeigniter, so this may be non relevant, or false.
Your node.js server listen to port 8010, which is non standard, that is why you need to indicate it in the URL.
You seems to imply codeigniter is already listening to the standard port (80).
The way I see, with no knowledge of codeigniter, to go around the issue would be to either host all the node.js url in codeigniter, and redirect them to port 8010:
Client call /node on port 80
CodeIgniter call /node on himself at port 8010
Node get the request and answer
Code igniter gove the answer to the client
Or the reverse, which would be to host any codeigniter URL in node.js, and redirect them to whatever port codeigniter will listen.
Or you will need to configure Apache to redirect the request to port whatever codeigniter on or 8010 depending of the url.

hiding port number through .htaccess node.js express

I am running two node servers on my website. 1 is a socket.io server for live streaming data on the main site and the other is streaming JSON data to a sub-domain api.site.com.
my main node is running on port 8001 and the second is running on 8080. I have been able to hide the port number for the first one in .htaccess using
RewriteCond %{SERVER_PORT} 8001
but am struggling to hide the 8080 port.
If I add in RewriteCond %{SERVER_PORT} 8080 and go to my api location api.site.com/prices/all I get 404 not found error and if I go to api.site.com:8080/prices/all everything still works.
How can I hide the port so api.site.com/prices/all works?
This is also slightly linked to my other question: here where I want to deny other .get attempts so api.site.com/price wont work.
You can put your config directly in the domain.conf folder the following works for me every time. Port here is 8888 change customise that and the domain to your settings.
<VirtualHost *:80>
ServerName mydomain.foobar
ServerAlias mydomain.foobar
ServerAdmin info#lakes.world
DocumentRoot /path/to/mydomain.foobar/httpdocs
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
ProxyPreserveHost On
ProxyRequests Off
ProxyPass / http://mydomain.foobar:8888/
ProxyPassReverse / http://mydomain.foobar:8888/
</VirtualHost>

Angular + Node(Express) + SSL integration

This is my first time deploying ssl. I have express node js module running at localhost:4000. I have generated the self-signed certificate and installed in the server and it is working. Now, I have my angularjs frontend running at localhost:3000(I am using http-server to run the angular code).
To make my point more clearer, here's is the code on the server side:-
// Import node js modules
var https = require('https')
var fs = require('fs')
var express = require('express')
// Load App configuration
var config = require('./config/config')
// Database Integration Here(mongodb)
// Initialize the express app
var app = express()
// App express Configuration
// parse application/json
app.use(bodyParser.json())
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true}))
app.use(cors())
app.set('serverHost', config.server.host)
app.set('serverPort', config.server.port)
app.set('serverUrl', config.server.url)
// Initializing various app modules
// Initialize the components
//Initialize the route(controller)
// Start the app with a given port no and mode
var env = process.env.NODE_ENV || 'development'
var httpsOptions = {
key: fs.readFileSync(__dirname + '/cert/server.key'),
cert: fs.readFileSync(__dirname + '/cert/server.crt')
}
https.createServer(httpsOptions, app).listen(app.get('serverPort'), function () {
// Server and mode info
console.log('The homerungurus backend running on server: '
+ app.get('serverHost')
+ ' and the port is: '
+ app.get('serverPort'))
console.log("The mode is: " + env)
})
As you can see I have installed the certs in the server.
I don't need a http-proxy because i will deploy the angular webserver on the standard port 443.
I am not able to understand few things:-
How to enable and set ssl certificate in my angular module so that
express and angular can communicate over ssl.
How will I display the cert of my backend express node to the browser?
I hope I have made my point more clearer.
Any help is appreciated?
Ok, where do we start...
You have a backend (express node js) running on port 4000, and a frontend (angularjs with http-server) running on port 3000, so you basically have two independent webservers running. When you say you "installed" the ssl certificate on the server, I assume you have it sitting in some directory but not actually installed on one of your servers.
You have several options to deploy your code, together with your SSL certificate. The best approach would be to seperate frontend from backend by urls.
That would mean that your frontend gets served from: https://frontend.example.com
and your backend gets served from https://backend.example.com (you can change the urls to whatever you want, so something like https://example.com or https://www.example.com is fine as well)
As far as I recall, if you have https:// on your frontend, you also need https:// on your backend, otherwise you will have problems with browsers security policies. You might also have to look for same origin policy, and allow on your server that https://frontend.example.com can access https://backend.example.com, but for that open a new ticket if you need it :D
The user would see the green symbol from https://frontend.example.com
I assume you know how you would change the backend url so your angular code would use https://backend.example.com instead of http://localhost:4000
To serve now your existing servers on port 443 (that is the default port for https and is always used if you say https://... but do not specify a port) you need an http proxy.
As http proxy (you can google for reverse proxy) you can take either apache or nginx, both are very common.
There are a couple of tutorials out there, how to setup nginx / apache which are OS specific, but Im sure you will manage. Dont forget to install mod_ssl and mod_http_proxy mod for apache (I dont remember if nginx needs something specifc as well)
A typical config for an apache reverse proxy would look like this:
<VirtualHost *:80>
# this part redirects all traffic from normal http to https
ServerName frontend.example.com
ServerSignature Off
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [NE,R,L]
</VirtualHost>
<virtualhost *:443>
# this is the actual part with some security enhancements
ServerName frontend.example.com
ServerAdmin webmaster#localhost
# be carefull with HSTS, it might break your setup if you
# do not know what you do. If you are not sure, do not
# comment the next line in
# Header always add Strict-Transport-Security "max-age=15768000"
# Enable SSL
SSLEngine on
# only strong encryption ciphers
# for reference https://community.qualys.com/blogs/securitylabs/2013/08/05/configuring-apache-nginx-and-openssl-for-forward-secrecy
# and no RC4 according to https://community.qualys.com/blogs/securitylabs/2013/03/19/rc4-in-tls-is-broken-now-what
SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"
SSLCompression Off
SSLCertificateFile /path/to/cert.pem
SSLCertificateKeyFile /path/to/privkey.pem
# this next line is not needed if you have a self signed cert
SSLCertificateChainFile /path/to/chain.pem
ServerSignature Off
RequestHeader set X-FORWARDED-PROTOCOL https
RequestHeader set X-Forwarded-Ssl on
ProxyPreserveHost On
# Ensure that encoded slashes are not decoded but left in their encoded state.
# http://doc.gitlab.com/ce/api/projects.html#get-single-project
AllowEncodedSlashes NoDecode
<Location />
# New authorization commands for apache 2.4 and up
# http://httpd.apache.org/docs/2.4/upgrading.html#access
Require all granted
ProxyPassReverse http://127.0.0.1:3000
ProxyPassReverse http://frontend.example.com/
</Location>
#apache equivalent of nginx try files
# http://serverfault.com/questions/290784/what-is-apaches-equivalent-of-nginxs-try-files
# http://stackoverflow.com/questions/10954516/apache2-proxypass-for-rails-app-gitlab
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule .* http://127.0.0.1:3000%{REQUEST_URI} [P,QSA]
RequestHeader set X_FORWARDED_PROTO 'https'
You will need the exact same twice, for the frontend like shown above and for the backend, where you replace port 3000 with 4000 and frontend.example.com with backend.example.com.
I hope this helps you a bit. Its not as complete as it could, but it should give you a hint how to setup your two http servers behind a http proxy to server your ssl certificate.
The above comment made by #chickahoona is more than enough. My solution is as follows:-
I removed http-server and used nginx for my frontend because i wanted to have html5 mode and for that I needed to have url rewriting.
I have used nginx as a proxy server rather than apache.
That's it and everything else is same as #chickahoona has pointed out.

How to configure my node.js application on a dedicated server to put it online?

I've installed node.js on my server(it is a virtual windows server). I am also having the domain. I want to run my node.js application on a port 8001 so that when I open, say http://example.com:8001/ it will open my application.
Actually, I am also having a PHP site running on Apache server on port 80(XAMPP). It is perfectly working fine when I open say, http://example.com.
Thanks
In apache, create a new vhost. You have to proxy all requests through apache to your node app as apache is listening to port 80.
<VirtualHost *:80>
ServerName example.com
ProxyRequests off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
<Location />
ProxyPass http://localhost:8001/
ProxyPassReverse http://localhost:8001/
</Location>
</VirtualHost>
If you are not on a name-based virtual host environment you can just start your Node.js server and it will be available to the world from the defined port. But if the server IP address runs many services using different domain names and you want your Node.js server to reply only from http://example.com:8001 you can use e.g. the vhost module on your node server to listen to specific domain only:
var express = require('express'),
host = require('vhost');
var app = express();
app.get('/', function(req, res) {
res.send("Hello from vhost");
});
var main = express();
main.use(vhost('example.com', app));
if (!module.parent) {
main.listen(8001);
}
You can also proxy the requests through a web server like Apache or nginx, but to have the service responding from port 8001 you would need to bind the web server to port 8001 in addition to 80 you are already using, and run your Node.js server on some other port.
Generally people prefer using the standard HTTP port and use a web server to reverse proxy traffic to the Node.js server running on a non-privileged port. As you already have the PHP application on your domain name you would then follow advice by #SamT and run your Node.js application from e.g. http://mynodeapp.example.com

Categories