hiding port number through .htaccess node.js express - javascript

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>

Related

Node.js socket.io with https on 3000 port

I want to run node.js and socket.io on the https. I redirect requests which are coming from server.example.com to http://example.com:3000
<VirtualHost server.example.com:80>
ProxyPass / http://example.com:3000/
</VirtualHost>
And this way i can access to socket.io.js file
https://server.example.com/socket.io/socket.io.js
To test node.js part, print socket.id in console.
Image : http://prntscr.com/jq81bz
Here is the client side, i connect to socket.io with this way.
Image : http://prntscr.com/jq830z
The client connects node.js server and print the socket.id. But there are many errors occurred in browser console. I think the client wants to connect again because of errors.
Image : http://prntscr.com/jq82ib <- server's console is on left
Those logs printed for just one connection.
You apache configurations must be changed as follow.
<VirtualHost *:443>
ServerName mysite.com
ServerAlias www.mysite.com
SSLEngine on
SSLProxyEngine On
ProxyRequests Off
SSLCertificateFile /etc/apache2/ssl/mysite.com.crt
SSLCertificateKeyFile /etc/apache2/ssl/mysite.com.key
SSLCertificateChainFile /etc/apache2/ssl/ca.cer
DocumentRoot /var/www/errorPages
ErrorDocument 503 /503.html
ProxyPass /503.html !
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
RewriteRule .* ws://localhost:3000%{REQUEST_URI} [P]
</VirtualHost>

Keycloak Admin Console showing a blank page

I have configured a Keycloak server with Apache at the front acting as a reverse proxy. Keycloak is running on http mode only, all the SSL is being handled by Apache. I've configured the whole system according to the official Keycloak docs.
The problem I'm facing is, on accessing the Keycloak admin console from a machine other than localhost, the page is blank (except the navbar). On accessing from the machine on which it is hosted (localhost), it works fine, but on accessing from any other machine it just shows a blank page. The server also does not throw any error. I'm attaching an image of the blank admin page below.
(source: firefoxusercontent.com)
Another thing to note would be, other pages, like my account page, are working fine. The problem is only with the main admin page. Also, I've noticed that the admin page is an Angular app, so that may be relevant.
Relevant configs and settings I'm using.
Keycloak settings (CLI commands).
embed-server --server-config=standalone.xml
/subsystem=undertow/server=default-server/http-listener=default/:write-attribute(name=proxy-address-forwarding,value=true)
/socket-binding-group=standard-sockets/socket-binding=proxy-https/:add(port=443)
/subsystem=undertow/server=default-server/http-listener=default/:write-attribute(name=redirect-socket,value=proxy-https)
Apache config.
<VirtualHost *:80>
DocumentRoot /var/www/html
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
Redirect permanent '/' https://%{HTTP_HOST}
</VirtualHost>
<VirtualHost *:443>
DocumentRoot /var/www/html
ProxyPreserveHost On
ProxyRequests Off
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
ProxyPass /auth http://127.0.0.1:8080/auth
ProxyPassReverse /auth http://127.0.0.1:8080/auth
SSLEngine on
SSLCertificateFile /etc/ssl/certs/oauth-server.crt
SSLCertificateKeyFile /etc/ssl/private/oauth-server.key
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
</VirtualHost>

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.

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.

Categories