Reverse Proxy Server: Basics

From The Uniform Server Wiki
Jump to navigation Jump to search

MPG UniCenter

MPG UniCenter

Uniform Server 3.5-Apollo
Reverse Proxy.

The previous page looked at reverse proxy architecture and introduced front and back-end servers. This page shows how to run a proxy server using the standard modules distributed with Apache. Before looking at any examples an understanding of the proxy commands is essential.

Proxy commands - directives

The most important command for running a reverse proxy has been covered Proxy Requests Off you may be surprised to learn only two other commands are required however there are others available these tend to be more application specific.

ProxyPass path url

ProxyPass: This command, maps a remote server into your proxy server’s name space.

path: Is the folder or folders that you tack onto the end of your domain for example http://fred.com/info/

url: URL to the remote server for example http://localhost:8086/ (you can also map a folder on this server)

ProxyPassReverse path url

ProxyPassReverse: This command masquerades one server as another. Apache adjusts URL's (location, Content-Location and URI headers) from the reverse-proxied server so they look as if they came from the server running the proxy engine.

path: Is the folder or folders that you tack onto the end of your domain for example http://fred.com/info/

url: URL to the remote server for example http://localhost:8086/

Net result, when a user types the following http://fred.com/info/ into a browser the contents from server http://localhost:8086/ will seamlessly appear in folder info.

Top

Example 1

The best way to understand this process is to run a few examples. You can manually set-up Uniform server alternatively if using mini server 20 copy the appropriate configuration file details for either method are provided below.

Uniform Server

Open Apache's configuration file: httpd.conf Located in folder: \udrive\usr\local\apache2\conf

At the bottom of this page locate the Vhost section and edit to look like the following:

NameVirtualHost *

<VirtualHost *>
 ServerName localhost:80
 DocumentRoot /www

ProxyRequests off
<Proxy *>
  Order deny,allow
  Deny from all
  Allow from 127.0.0.1
</Proxy>

ProxyPass         /info/  http://localhost:8086/
ProxyPassReverse  /info/  http://localhost:8086/

</VirtualHost>

Make sure to un-comment the line NameVirtualHost * (as shown)

Run Example:

  1. Save the file
  2. Re-start both servers - Uniform Server first followedby mini server 6.
  3. Type following http://localhost/info/ into your browser

The index page from server_b will display use the links to check out sites test1, test2 and test3 alternatively type the following URLs:

  1. http://localhost/info/test1/index.html
  2. http://localhost/info/test2/index.php
  3. http://localhost/info/test3/index.php

Top

Mini-Server

Locate folder: \udrive\usr\local\apache2\conf inside this are sub-folders corresponding to the examples. Open folder example 1 and copy file httpd.conf up one level into folder \udrive\usr\local\apache2\conf and let it overwrite the existing file.

  1. Re-start mini-server 20 and type
  2. Type following http://localhost/info/ into your browser

The index page from server_b will display use the links to check out sites test1, test2 and test3 alternatively type the following URLs:

  1. http://localhost/info/test1/index.html
  2. http://localhost/info/test2/index.php
  3. http://localhost/info/test3/index.php

Testing

Explore the three sites, you will quickly discover. The first two sites work fine however that third site fails to render even worst none of the page links work.

I included site test3 to demonstrate this failure. I recommended when creating a site using clean URLs to avoid problems all links shall be server root relative. Clearly this has introduced problems when running through a proxy.

Problem

Apache’s proxy engine does not rewrite links within a served page it only manipulates what is typed or would be typed in a users browsers address bar. When Apache serves a page from a remote server it adjusts the returned page to match that of a user request.

Solution

One solution is to install and use mod_proxy_html this was specifically designed for rewriting links in a severed page resolving this type of problem.

The above software is extremely powerful and will be covered latter. However lets look at an alternative to resolve this particular problem covered in example 2.

Top

Example 2

Test3 is a self-contained single page web site using server relative links. It’s being proxied and none of the page links work; these include images, css and access to other pages.

The site is a single page residing on a remote server, it contains links resolvable by that server and its corresponding htaccess file. This is irrelevant to a user; the page just sits there in a browser. Click one of the links a browser’s task is to create a new resource request, be it for images, css or even a new page.

Top

Resource request

A browser looks at a link and creates a resource request using the following rules:

  • If the link starts with a forward slash (/info) it adds only the domain name to complete the Url http://localhost/info.
  • If the link starts with two periods (../info) or no forward slash (info) it considers this a relative link.
    It checks the currently displayed page (in the address bar) and constructs a new request relative to this.
    For example current page http://localhost/fred/news/ link ../info gives http://localhost/fred/info.
  • If the link is a fully qualified URL (http://www.someother.com) its just uses that (Note: This breaks out of any reverse proxies.

Top

URL mapping

Looking at our problem links:

Browser Displays:
http://localhost/info/test3/index.php
server_a server_b
Page link Resource request Required Remote server
/test3/mpg.gif http://localhost/test3/mpg.gif http://localhost/info/test3/mpg.gif http://localhost:8086/test3/mpg.gif
/test3/home http://localhost/test3/home http://localhost/info/test3/home http://localhost:8086/test3/home
/test3/about http://localhost/test3/about http://localhost/info/test3/about http://localhost:8086/test3/about

Looking at the mapping it looks impossible. One thing we know the initial page can be accessed (relative link) hence not a problem. When a resource is requested its only folder "info" preventing access to pages on server_b, removing this we have:

Browser Displays:
http://localhost/info/test3/index.php
server_a server_b
Page link Resource request Required Remote server
/test3/mpg.gif http://localhost/test3/mpg.gif http://localhost/test3/mpg.gif http://localhost:8086/test3/mpg.gif
/test3/home http://localhost/test3/home http://localhost/test3/home http://localhost:8086/test3/home
/test3/about http://localhost/test3/about http://localhost/test3/about http://localhost:8086/test3/about

Top

Proposed solution

Remember Apache's proxy engine maps servers and folders (not files) this gives the following:

Browser Displays:
http://localhost/info/test3/index.php
server_a server_b
Page link Resource request Required Remote server
/test3/mpg.gif http://localhost/test3/mpg.gif http://localhost/test3/mpg.gif http://localhost:8086/test3/mpg.gif
/test3/home http://localhost/test3/home http://localhost/test3/home http://localhost:8086/test3/home
/test3/about http://localhost/test3/about http://localhost/test3/about http://localhost:8086/test3/about

OK we need to bite the bullet and have a new folder (test3) in our name space hence we can map this on both servers using the following:

ProxyPass
ProxyPassReverse
/test3/
/test3/
http://localhost:8086/test3/
http://localhost:8086/test3/

Top

Implementaion

Time to see if this solution works, edit httpd.conf as shown.

If using mini-serer 20 open folder example 2 and copy file httpd.conf up one level into folder \udrive\usr\local\apache2\conf and let it overwrite the existing file.

NameVirtualHost *

<VirtualHost *>
 ServerName localhost:80
 DocumentRoot /www

ProxyRequests off
<Proxy *>
  Order deny,allow
  Deny from all
  Allow from 127.0.0.1
</Proxy>

ProxyPass         /info/  http://localhost:8086/
ProxyPassReverse  /info/  http://localhost:8086/

ProxyPass         /test3/  http://localhost:8086/test3/
ProxyPassReverse  /test3/  http://localhost:8086/test3/ 

</VirtualHost>

Run Example:

  1. Save the file
  2. Re-start both servers - Uniform Server first followed by mini server 6.
  3. Type following http://localhost/info/ into your browser

Alternatively

  1. Re-start server 20
  2. Type following http://localhost/info/ into your browser


The index page from server_b will display use the link to check out the site test3 alternatively type the following URL:

  1. http://localhost/test3/index.php

Note: If you wish; change the link on the index page so the transition does not look odd.

Top

Example 3 - Mod Rewrite

Mod Rewrite is very flexible one of its more powerful tags is the “P” tag. The rewrite action is a fully qualified location followed by the [P] tag, which means perform a proxy request. The resource location requested is a remote server, this resource is served as if it is a local resource.

RewriteRule ^/info/(.*)$ http://localhost:8086/$1 [P,QSA]

  1. /info/ the rule is looking for any requests to folder "info"
  2. (.*) Save anything after the folder "info"
  3. http://localhost:8086 Url of our proxy server
  4. /$1 tack onto the end of the proxy server what was stored in 2)
  5. [P,QSA] Forces a proxy request from the server. Note any remaining rules will not be executed [L] is assumed.

Lets set our server to run using mod rewrite rules, edit httpd.conf as shown. Located in folder: \udrive\usr\local\apache2\conf

If using mini-serer 20 open folder example 3 and copy file httpd.conf up one level into folder \udrive\usr\local\apache2\conf and let it overwrite the existing file.

NameVirtualHost *

<VirtualHost *>
 ServerName localhost:80
 DocumentRoot /www

ProxyRequests off
<Proxy *>
  Order deny,allow
  Deny from all
  Allow from 127.0.0.1
</Proxy>

RewriteEngine On
RewriteRule ^(/info/)(.*)$  http://localhost:8086/$2 [P,QSA]
RewriteRule ^(/test3/)(.*)$  http://localhost:8086$1$2 [P] 

ProxyPassReverse / http://localhost:8086/

</VirtualHost>

Run Example:

  1. Save the file
  2. Re-start both servers - Uniform Server first followed by mini server 6.
  3. Type following http://localhost/info/ into your browser

Alternatively

  1. Re-start server 20
  2. Type following http://localhost/info/ into your browser


The index page from server_b will display use the link to check out the site test3 alternatively type the following URL:

  1. http://localhost/test3/index.php

Note: Mod Rewrite offers finer control.

Top

Summary

The above has attempted to show the power of using Apache as a reverse proxy. It’s not overly difficult; you can find more tutorials on the Internet that explains reverse proxying better. What I have provided are working examples allowing you to hack around and follow any examples provided.

The above proxy examples are suitable for simple sites however you will at some time need to rewrite page links on-the-fly. This can be achieved using the mod_proxy_html module describe on the next page.

Top


Ric