1

I have created a reverse proxy for my node server that runs on localhost, so that it can be served over HTTPS.

The forwarding works grate, however when the app tries to make requests I get:

Mixed Content: The page at 'https://foo.com/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://localhost:8888/graphql?query=%7Bnotifications(userid)%7Bid%2C… This request has been blocked; the content must be served over HTTPS.

Vhost config:

<VirtualHost *:443>
   ServerName www.foo.com
   ServerAlias foo.com
   DocumentRoot /var/www/foo/
   ErrorLog /var/www/foo/error.log
   CustomLog /var/www/foo/requests.log combined

   SSLEngine on
   SSLProtocol all -SSLv2
   SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5
   SSLCertificateFile "/etc/letsencrypt/live/foo.com/cert.pem"
   SSLCertificateKeyFile "/etc/letsencrypt/live/foo.com/privkey.pem"

   ProxyPreserveHost On
   ProxyRequests Off
   ProxyPass / http://localhost:8888/
   ProxyPassReverse / http://localhost:8888/

</VirtualHost>

What is missing from my setup?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Edmond Tamas
  • 3,148
  • 9
  • 44
  • 89

2 Answers2

1

You are openning the page on https://foo.com/, but URLs within your page contain hardcoded localhost domain and port. While rendering the page, client browser will try to fetch 'http://localhost:8888/graphql effectively skipping apache (which is running on port 80, on server foo.com) and hitting directly your node app, which will 1) work only if you run the browser from the very same machine where you have your node app running, and 2) even then, you will get the above error since some page assets are loaded using http.

When you use relative URLs (for example URL that begins with /), browser will prepend the base URL, resulting in https://foo.com/graphql.

Absolute vs relative URLs

Dusan Bajic
  • 10,249
  • 3
  • 33
  • 43
0

You need to add a SSL certificate to your node.js app. Enabling it on apache won't help since the apache is forwarding the requests to your node.js app on port 8888 (which communicates on plain http and not https). That's why you get the mixed content error. The initial request is on https on apache then forwarded to http to node.js

Steps to configure node.js app with a SSL certificate (you can use a self-signed certificate or a commercial one).

First you have to use ssl-root-cas available via npm. The configure it as follows:

'use strict';

var https = require('https')
  , cas
  ;

// This will add the well-known CAs
// to `https.globalAgent.options.ca`
require('ssl-root-cas').inject();

cas = https.globalAgent.options.ca;

cas.push(fs.readFileSync(path.join(__dirname, 'ssl', '01-ssl-intermediary-a.pem')));
cas.push(fs.readFileSync(path.join(__dirname, 'ssl', '02-ssl-intermediary-b.pem')));
cas.push(fs.readFileSync(path.join(__dirname, 'ssl', '03-ssl-site.pem')));

Try and see if that works!

Bogdan Stoica
  • 4,349
  • 2
  • 23
  • 38
  • Thank you very much for the solution, initially I had https set up in my express server, but after deployment onto my AWS server, it couldn't serve contend on 443 because on Linux apps can use ports bellow 1200 only wit sudo admin rights. Well I didn't want the overhead, so I went towards the Apache proxy which works quite well. Thanks anyway, mate! – Edmond Tamas Jul 04 '17 at 12:30