Bypass the ISP Restriction on Port 80

A couple of days ago, my friend Jeffery registered a new domain name. He pointed that domain to his in-house server and realized that his Internet Service Provider, Cox Communications, has blocked some common ports, namely 80 and 443, to prevent customers using their internet service to host websites.

As a result, Jeffery had to append the port number explicitly, which is not only a pain in life but also a significant impact on SEO. So he came to me for help, and I made him satisfy by using an Apache reverse-proxy server.

TD;LR

Use another server listening on port 80 outside the ISP firewall as a reverse-proxy server.


My first thought was to use some kind of third-party redirecting services that allow users to redirect to port 8888. But Jeffery said that he wants to give out his own domain, instead of something like a bit.ly domain. This is totally understandable, as his visitors can stay on his own domain on port 80 all the time, which is great for user experience.  Basically, he wants some kind of DNS service that allows binding to ports or port-forwarding.

But there is no such service. DNS simply resolves a domain name to an IP, without providing any information about the port. It is up to the client to choose a port to use. Unless another port is specified in the URL, browsers will use ports 80 for HTTP and 443 for HTTPS. Since Jeffery’s ISP is restricting all incoming traffic on ports 80 and 443, there is no way to visit his server without explicitly specifying the port. As a result, the only way to listen to port 80 is to use a proxy server running outside the Cox firewall is needed.

I have an in-house server as well, and I am using Charters Communications, which does not restrict incoming traffics on any port. ୧(๑•̀◡•́๑)૭ Thumb up Charters!

I thought, my server can act as a proxy server for Jeffery. So I told him to point his domain name to my server IP address, I will then reverse-proxy all requests to whatever port on his server. The setup process is pretty simple.


Set Up DNS Record

Depending on whether he wants to park his root domain or some sub-domain on my server, he can choose to set an A record on his root domain (using @.root.domain) or set an A record on his sub-domain (using sub.root.domain.) Jeffery opted for parking the root domain on my server so that visitors who visit his root domain will get proxied as well.

NAME             TYPE   TTL    DATA
@.liyinxue.com   A      1h     96.40.185.68

All incoming traffics will now be sent to my server.


Set Up Apache Virtual Host

By default, Apache provides a single host configuration. I have enabled virtual hosts since I have been running multiple websites on this LAMP server.

To enable virtual hosts on a newly installed Apache server, create a new file in /etc/apache2/sites-available/[SITENAME].conf.

In my case, it is /etc/apache2/sites-available/liyinxue.com.conf.

The file content should be as following:

<virtualhost *:80>
        ServerName         liyinxue.com
        ServerAlias        *.liyinxue.com
        ServerAdmin        me@liyinxue.com
</virtualhost>

ServerName tells Apache that, this configuration is for requests to the domain liyinxue.com, so settings here will apply to liyinxue.com and won’t affect any other virtual hosts.

ServerAlias tells Apache that, all subdomains under liyinxue.com belong to this virtual host.

ServerAdmin provides an admin email. It will be shown on Apache default error pages like 404 page.

Save the file and enable the virtual host with

a2ensite liyinxue.com.

Then restart Apache server with

/etc/init.d/apache2 restart.

Now Apache should be configured to respond to requests to liyinxue.com. A 403 error will yield because we did not specify any DocumentRoot for this virtual host. Do not worry about this error, because we will be configuring reverse-proxy, and a DocumentRoot it is not needed in this case.


Set Up Apache Proxy Server

The next step is to configure my server to get content from his server on port 8888 and returns content to the client.

Reopen the virtual host configuration file and add some lines to make it look like this:

<VirtualHost *:80>
        ServerName         liyinxue.com
        ServerAlias        *.liyinxue.com
        ServerAdmin        me@liyinxue.com
        ProxyPreserveHost  On
        ProxyRequests      Off
        ProxyPass          /   http://liyinxue.ddns.net:8888/
        ProxyPassReverse   /   http://liyinxue.ddns.net:8888/
</VirtualHost>

ProxyPreserveHost is set to On. When enabled, this option will pass the Host: line from the incoming request to the proxied host. Note that on Apache website, it is said that this option should normally be turned Off. But since I am proxying all traffic to another fully functional server, I set it to On. Thus, Jeffery may make use of the original Host header information.

ProxyRequest is set to Off to prevent Apache httpd from functioning as a forward proxy server. Do not enable proxying with ProxyRequests unless you have secured your server. Open proxy servers are dangerous both to your network.

ProxyPass line redirects everything on / to http://liyinxue.ddns.net:8888/ which is Jeffery’s server on port 8888, while ProxyPassReverse lets Apache httpd adjust the URL in the Location, Content-Location and URI headers on HTTP redirect responses. This is essential when Apache httpd is used as a reverse proxy (or gateway) to avoid bypassing the reverse proxy because of HTTP redirects on the backend servers which stay behind the reverse proxy.

Then save the file and restart Apache to apply the configuration.

/etc/init.d/apache2 restart.

Now the Apache server should be configured to proxy all incoming requests.


By doing this, the client will be always visiting with Jeffery’s domain, on port 80.

The proxy process is invisible to the client, but the client will notice a significant delay, because under the hood, upon receiving a request, my server is sending another request to Jeffery’s server (:8888), wait for the content, and then send it back to the client. This extra data flow will slow down the connection to Jeffery’s server. But since Jeffery and I are physically close to each other, the delay should not make a real-life difference.

There is a potential risk for providing the reverse-proxy server though.

As far as the client can see, the server IP associated with Jeffery’s domain name is my IP. This means that any content served in his domain name is publically served from my server. If he provides any illegal materials, I will be the one in charge. So do this at your own risk. Only do this for someone you really trust.

Leave a Reply

Your email address will not be published. Required fields are marked *