A Simple ReverseProxy Using PHP

03-29-2020 - 1 minute, 59 seconds - Coding PHP

In the course of the last week i moved some websites from my self managed VPS to an designated webhoster. Once moved, i encountered the problem that i could not use ngnix's proxy_pass feature. So i wrote myself a little ReverseProxy using PHP.

I wanted to move the websites from the VPS to an Webhoster because i wanted to save me the trouble of keeping everything up to date. Also managing a mailserver for multiple domains was kind of a nightmare for me, thanks to every mail provider reacting differently to new mail server IPs and mailserver settings. Mails sent from customer domains sometimes were flagged as spam or not deliverd at all...

Once i began moving everything, i realized that the new webhoster doesn't allow setting up a reverse proxy, which i needed for one of the domains. Since i just needed a very, very, simple reverse proxy (just simple GET requests really), i decided to just write a little proxy in PHP instead of not using the webhoster after all.

The reverse proxies code

First thing to do, is ensuring all requests land at your PHP script. For Apache, change your .htaccess file to something like this:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]

Next we need the index.php to redirect every request to the URL the real service lives at. I am using PHPs cURL module for that.

<?php
//set these

$external_url_link_replace = 'service.example.com';
$local_url_link_replace = 'example.com';
$external_url_base = 'https://' . $external_url_link_replace;

$external_url = $external_url_base . $_SERVER['REQUEST_URI'] . $_REQUEST['QUERY_STRING'];

function httpGet($url)
{
    $ch = curl_init();  

    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
    curl_setopt($ch,CURLOPT_HEADER, false); 
    curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');

    $output=curl_exec($ch);

    curl_close($ch);
    return $output;
}

// GET CONTENT
$origText = httpGet($external_url);

// REPLACE LINKS
$fixedText = str_replace($external_url_link_replace, $local_url_link_replace, $origText);

//print result
print $fixedText;
?>

What this does is taking the requested URL, replacing it with real services URL and sending a GET request there. Next thing the code does is saving the result in $origText. Then all links contained in $origText are replaced by links to the reverse proxy URL. Now all that's left to do is printing the $fixedText.

PS: Of course PHP certainly is not the right tool to implement a reverse proxy. Letting the server handle that would be a much cleaner solution. Also this solution works only with the simplest GET requests. Anything more sophisticated will not work.

Next Post