1
votes

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?

2
did you make sure all urls in your app are relative?Dusan Bajic
All urls have the form of http://localhost:8888/Edmond Tamas
Can you make them relative?Dusan Bajic
I have tried:localhost:8888/graphql but this leads to another error: XMLHttpRequest cannot load localhost:8888/graphql - Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.Edmond Tamas
what if you use only /graphqlDusan Bajic

2 Answers

1
votes

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

0
votes

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!