Advanced Reverse Proxy

You are here:
< Back

Introduction

In a previous article, we explained how to use OpenLiteSpeed as reverse proxy. In that case the request URI needed to be the same in the frontend as the backend, otherwise a 404 Not Found Error would be returned.

In this guide we will give examples for more advanced reverse proxy usage for two scenarios: proxy a frontend URI to different backend URI, or mask the URI.

Preparation

Let’s use 3 internal servers for demonstration purposes:

  1. 10.211.55.9, mapped to the www.centos7.local domain
  2. 10.211.55.10, mapped to the www.ubuntu.local domain
  3. 10.211.55.11, mapped to the www.centos8.local domain

Each server has the index.php file with following code:

<?php
echo "SCRIPT_FILENAME: ".$_SERVER["SCRIPT_FILENAME"]."<br>" ;
echo "SERVER ADDR: ".$_SERVER["SERVER_ADDR"]."<br>";
echo "HTTP_HOST: ".$_SERVER['HTTP_HOST']."<br>";

This allows us to determine which backend and what file we are requesting with.

We will use www.centos7.local as the main site, and do a reverse proxy to the other two servers under different URIs. The idea is to use RewriteCond and RewriteRule to control the URI proxying.

Examples

Here are two simple examples:

Example 1

We want to proxy all of the request query strings that contain ubuntu to www.ubuntu.local, and all of the query strings that contain centos8 will pass to www.centos8.local.

RewriteEngine On
RewriteCond %{QUERY_STRING} centos8
RewriteRule ^(.*)$ http://centos8/$1 [P,E=Proxy-Host:www.centos8.local,L]
RewriteCond %{QUERY_STRING} ubuntu
RewriteRule ^(.*)$ http://ubuntu/$1 [P,E=Proxy-Host:www.ubuntu.local,L]

After change the rewriterule ,  OpenLiteSpeed must be restarted in order to take effect.

Now if you check the URI and page, you will see the request www.centos7.local/index.php?ubuntu has been proxied to www.ubuntu.local, the request www.centos7.local/index.php?centos8 has been proxied to www.centos8.local, and all other requests remain on the current server.

Example 2

In this example, we will make `index.php?ubuntu2` proxy to  `http://www.ubuntu.local/new-uri.php`, while masking the URL so that it remains `index.php` instead of showing `new-uri.php`.

Create `new-uri.php` in the ubuntu server with same code to tell us the script name and server address so we don’t get lost.

Add RewriteRule and restart OpenLiteSpeed.

RewriteEngine On

RewriteCond %{QUERY_STRING} centos8
RewriteRule ^(.*)$ http://centos8/$1 [P,E=Proxy-Host:www.centos8.local,L]

RewriteCond %{QUERY_STRING} ubuntu2
RewriteRule ^(.*)$ http://ubuntu/new-uri.php?$1 [P,E=Proxy-Host:www.ubuntu.local,L]

RewriteCond %{QUERY_STRING} ubuntu
RewriteRule ^(.*)$ http://ubuntu/$1 [P,E=Proxy-Host:www.ubuntu.local,L]

Remember, the order of the rules are critical, as in this case, we have RewriteCond for string `ubuntu` and `ubuntu2`, so we will have to place the most narrow condition before others. Also, don’t forget the `[L]` flag. This will tell the rewrite engine to stop further processing the rule, because for the string `ubuntu2`, both

RewriteCond %{QUERY_STRING} ubuntu2 

and

RewriteCond %{QUERY_STRING} ubuntu

will match. It needs to be stopped after the first match.

Troubleshooting

If you are having trouble with rewrite rules, you can enable the rewrite log to help you to analyze the behavior of your rules.

You can check the output in the server log, found by default at /usr/local/lsws/logs/error.log .

You should see lines like this:

[REWRITE] Rule: Match '/index.php' with pattern '^/index.php', result: 1
[REWRITE] set ENV: 'Proxy-Host:www.ubuntu.local'
[REWRITE] Source URI: '/index.php' => Result URI: '/new-uri.php'

Look at the first line, ending with result: 1. Any positive value means the condition matches. A negative value means the condition does not match.

Another useful tool is RegExr a regular expression test tool. This will help you to tweak and verify your rewrite rule behaves as intended.

And finally, since OpenLiteSpeed is compatible with Apache’s mod_rewrite syntax, you can also check Apache documentation for more ideas.