Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:-

  1. How to enable and set ssl certificate in my angular module so that express and angular can communicate over ssl.
  2. 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?

like image 538
tumulr Avatar asked Sep 24 '22 02:09

tumulr


1 Answers

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.

like image 58
chickahoona Avatar answered Sep 26 '22 02:09

chickahoona