Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Easy reverse proxy for serving images over ssl

I created a simple web-based email client like gmail. I want to display images, but in order to do it with my ssl site, I need all images served over ssl (otherwise I get "mixed-content" warnings). So I need a reverse proxy like gmail has to serve those images.

I will rewrite all image urls in the email to point at the reverse proxy. For example:

My reverse proxy is https://myreverseproxy.com

original image url http://stuff.com/image1.jpg

I will rewrite the url to be https://myreverseproxy.com?image-url=http://stuff.com/image1.jpg

When the reverse proxy gets the request "https://myreverseproxy.com?image-url=http://stuff.com/image1.jpg" it will get the original image from the query parameter image-url (http://stuff.com/image1.jpg), fetch the image, and return it to the requester of https://myreverseproxy.com?image-url=http://stuff.com/image1.jpg.

Are there any services that do this out of the box? Could I write one that's simple? Are there any libraries or solutions already for this that I could just install somewhere?

I'm open to any language and any platform...I just want this issue resolved.

like image 626
richard Avatar asked Apr 03 '16 04:04

richard


2 Answers

I would suggest the same thing as Tudor: a proxy written in node.

However, I would advise using a more broadly used and tested library such as node-http-proxy. It is really simple to setup, and will achieve what you need in less than 20 lines of code.

var httpProxy = require('http-proxy')

httpProxy.createServer({
  target: {
    host: 'stuff.com',
    port: 80
  },
  ssl: {
    key: fs.readFileSync('./ssl-key.pem', 'utf8'),
    cert: fs.readFileSync('./ssl-cert.pem', 'utf8')
  }
}).listen(443);

If a client then accesses https://reverseproxy.com/image.png, the process would go as follows

enter image description here

I have assumed in this schema that the reverse proxy runs on a different server as the webserver serving the images, but this does not have to be the case. If they both run on the same server, just use host: 'localhost' in the target section.

--

Just in case you are not familiar with Node, here's what you need to do in order to quickly run this setup.

  • Install Node
  • Create a new file containing the code in yourprojectpath/index.js
  • Generate a package.json file by running npm init in your project's directory
  • Run npm install --save http-proxy to install the http-proxy library and be able to use it in the code

You should now be able to run the reverse proxy by running

node index.js

If you are planning on using this in production, I highly recommend you take a look at PM2. It is a process manager for node which basically ensures that your application is always running, no matter what. In particular, it will restart it if any kind of exception is thrown from the application and would have caused it to terminate.

Installation:

npm install -g pm2

Usage:

pm2 start index.js

A few more notes:

  • make sure that your .pem files have appropriate permissions and owner. chmod 400 is usually a good option (only readable by owner). The user running the Node application should be able to read them, though.
  • if your server runs behind a (software or hardware) firewall, you may need to open your port 443 to incoming traffic
  • depending on your SSL certificate provider, you might need to convert the files it will provide you to the PEM format
  • if needed, node-http-proxy supports additional options such as adding headers when a request is proxied
  • the script I presented above assumes you have ssl-key.pem and ssl-cert.pem in the same directory as it

Hope that helps! And just ask if something looks unclear to you

like image 116
christophetd Avatar answered Sep 28 '22 09:09

christophetd


Here's how to create self-signed certificates, if you don't have any

Nodejitsu docs

Now for the code, which is written in node.js:

HTTPS proxy

...and a screenshot :)

screenshot

like image 36
Tudor Ilisoi Avatar answered Sep 28 '22 09:09

Tudor Ilisoi