Skip to content

Instantly share code, notes, and snippets.

@adrienne
Created December 18, 2011 09:30
Show Gist options
  • Save adrienne/1492855 to your computer and use it in GitHub Desktop.
Save adrienne/1492855 to your computer and use it in GitHub Desktop.
Private DNS Masking

Private DNS Masking

Using Apache Virtual Hosts and mod_proxy for Fun & Profit

So I realized the other day that I was typing the same URLs about a zillion times a day. Even with address bar completion in Firefox and/or Chrome, there is still a lot of wasted effort trying to get to a given site. (URL completion doesn't help much when one of your sites is http://server.somethingorother.net/~atravis/ThingOne and another is http://server.somethingorother.net/~atravis/ThingTwo, for example.)

What I wanted was to be able to type in, say, http://thing1.dev and have my system just know that that actually meant I wanted to go to my ThingOne development site. I knew of a lot of ways to do part of that, but no way to solve the whole problem.

Then, in a fit of serendipity (and research), I hit upon this technique!

Note that the directions below presuppose a fair level of comfort with your operating system. I've tried to make the directions clear, and gone into a lot of detail about (likely) file paths and locations, but ultimately if the idea of installing and configuring Apache gives you hives, this trick is probably not for you.

Preliminaries

1. Administrator Access

You will probably not be able to make this all work unless you have administrator or root access to your computer; some of the necessary files most likely have root permissions required.

2. Apache

You need to have Apache installed on your local machine. It's also simplest if it's listening on port 80, which is the standard port for http; otherwise you have to type in :8080 (or whatever port it's listening on) after everything, which is just annoying and you'll forget about it all the time.

The easiest way to accomplish that under Windows is to use XAMPP (get it here). Run the installer and make sure to select "Install Apache as a service". (Get the actual installer, not the zip file, for maximum convenience.)

Most common Linux distros already have Apache available, and it's not unlikely that it's even installed and listening on port 80 -- though you may have to do a little research to sort out how to get it configured properly. If your distro doesn't have it, or if you just don't feel like figuring out the configuration differences, XAMPP is also available for Linux.

Mac folks, you're on your own. :) I know there are several MAMP stacks out there, but I don't know anything about which ones are workable.

3. mod_proxy

You must have both mod_proxy and mod_proxy_http enabled in your Apache installation. Check whether they are active by looking in the file httpd.conf, which is Apache's main configuration file.

In XAMPP, this file is located by default at [DRIVELETTER]:\XAMPP\apache\conf\httpd.conf, and by default mod_proxy is enabled but mod_proxy_http is commented out with a hash mark # at the beginning of the line. Removing the hash mark will enable it, though you will have to restart Apache for the change to take effect.

Note that allowing Apache to act as a proxy can be dangerous. That's why we're not going to do it! We need to add the directive ProxyRequests Off to Apache's configuration.

  • In XAMPP, this directive is already active, contained in the file [DRIVELETTER]:\XAMPP\apache\conf\extra\proxy.conf -- but go verify that, because you do not want to risk the security of your system!

  • In other Apache distributions, such as for Linux or Mac systems, this directive will most likely be
    in the main httpd.conf file; if you cannot find it, add it now by pasting it on a line of its own.

4. Configuration Files

At this point, we should go ahead and find the configuration files you'll need -- the configuration file for virtual hosts, and your actual operating system's hosts file. You'll probably find it helpful to stick shortcuts or symlinks to these files in a central location, so that you don't have to hunt for them every time you need to make changes. So, go ahead and create a directory somewhere reasonable, and call it VirtualHostsConfig or something similar.

Apache .conf file

Virtual hosts are configured through Apache's httpd.conf file again, but we're going to actually pull them out into a linked file.

  • If you're running XAMPP, this file is already created, and you can find it at [DRIVELETTER]:\XAMPP\apache\conf\extra\httpd-vhosts.conf. Go ahead and create a shortcut to that file in your new VirtualHostsConfig directory. Then, open it up in a text editor, and uncomment the following line (remove the hash marks from the beginning): NameVirtualHost *:80

  • Other Apache packages may also have the config for virtual hosts separated out; search your Apache config directory (and any subdirectories) for a file called vhosts.conf or a directory called vhosts.

    However, it's equally likely that any existing vhosts configuration is at the bottom of the main httpd.conf file. We don't want to leave it there, so let's go ahead and separate it out.

    1. Create a new text file in the same directory as httpd.conf. Call it httpd-vhosts.conf, and create a shortcut or symlink to it in your new VirtualHostsConfig directory. Open it in a text editor, and paste this in as the first line:

           `NameVirtualHost *:80`
      
    2. Then, search httpd.conf for the string VirtualHost, and if you find it, cut the whole block of Virtual Hosts information and configuration out and paste it into your new vhosts.conf file. (It should be pretty easy to spot where the block begins and ends.)

    3. Lastly, put the following into your main httpd.conf file, on a line by itself (replace the path information with the correct path info for your system):

           Include "/FULL/SERVER/PATH/TO/THIS/DIRECTORY/vhosts.conf"
      

Now you've got a separate file with your virtual hosts info in it, and a shortcut or symlink to that file in a directory by itself.

OS hosts file

You also need to find, and create a shortcut to, your operating system's hosts file.

  • In Windows, you can just open your VirtualHostsConfig directory, right-click in the empty space, and choose New -> Shortcut from the context menu. It will prompt you for the location of the shortcut; paste the following in as the path:

      %WinDir%\System32\drivers\etc\hosts
    
  • On a Mac, the directory containing the hosts file is hidden by default. To get to it via the Finder, go to the toolbar, then choose Finder -> Go -> Go to Folder... and type in /etc. You should see a hosts file. If not, repeat the above steps and type in /private/etc. Once you find the file, make a shortcut in your VirtualHostsConfig directory.

  • On Linux, your hosts file is most likely in /etc/hosts -- create a symlink to it in your VirtualHostsConfig directory.

After finding your hosts file and creating a shortcut/symlink, open the file in a text editor and ensure that the following two lines are there and uncommented (have no hash marks at the beginning of the line). (If the lines are not there, paste them in.)

    127.0.0.1			localhost
    ::1                 localhost

Both 127.0.0.1 (IPv4) and ::1 (IPv6) are special IP addresses that mean "myself", the machine containing the hosts file. This tells your computer that it should definitely resolve requests for the domain "localhost" to your local machine. (This would normally happen anyway, but this makes absolutely sure.)

Setup

What we're going to do is use mod_proxy in reverse proxy mode, which means we tell Apache "I'm going to ask for a location, but I want you to give me some other location instead, using some predetermined substitution rules." We're going to do this by setting up Virtual Hosts with proxy directives.

Names

The first step is to decide on a naming convention. My personal naming convention is to use short, descriptive host names, with a fake TLD that tells me what's actually going on. So:

  • proj1.dev is the remote development server for "Project One".
  • proj1.stg is the remote staging server for the same project.
  • proj1.prod is the ultimate production server for the same project.
  • proj1.local is a non-reverse-proxied virtual host for the project, located on my local machine. (This tutorial doesn't cover local virtual hosts; there's plenty of good info out there about them already!)

hosts File Addition

Next, we need to add all these domains to our hosts file. Go to your VirtualHostsConfig directory to find the shortcut, then open up that file in a text editor. Put in your new "domains", one per line, as follows:

    127.0.0.1            proj1.dev
    127.0.0.1            proj1.stg
    127.0.0.1            proj1.prod

(Remember that 127.0.0.1 is a special IP address that means "myself".)

If you want to put in more than one project right now, feel free! Your hosts file can contain as many lines as you want.

Virtual Host Configuration for Apache

Go to your VirtualHostsConfig directory again, and this time open up the httpd-vhosts.conf file in a text editor. For each of the domains we are trying to create, we need to create a block that looks like this:

    <VirtualHost *:80>
        ServerName proj1.dev
        ProxyPreserveHost On
        ProxyPass / http://somedomain.com/somesite/
        ProxyPassReverse / http://somedomain.com/somesite/
    </VirtualHost>

Let's look at that line-by-line:

  1. <VirtualHost *:80>

    This tells Apache that we're starting a VirtualHost directive, and that the directive applies to anything Apache hears on port 80 (which is the HTTP standard port).

  2. ServerName proj1.dev

    This tells Apache the server name that the directive is talking about. Combined with the above line, what Apache now knows is, "whatever else is in this block applies anytime I see this server name asked for via HTTP."

  3. ProxyPreserveHost On

    This says, "don't change anything about the host name you see; just take it as it comes in."

  4. ProxyPass / http://somedomain.com/somesite/

    This is an instruction to take everything after the server name (that's the first /) and route it as if it were preceded by the URL given.

    So, if we ask for http://proj1.dev/a_directory/a_file.html, that request will actually get routed to http://somedomain.com/somesite/a_directory/a_file.html for us.

    Note that the URL must end in a trailing slash!

  5. ProxyPassReverse / http://somedomain.com/somesite/

    This does the same thing backwards, telling Apache to grab anything that comes back from one of those rerouted requests, and pass it through as if it's coming from our fake domain.

    That means if we go to http://proj1.dev, and we click a link to contact-us.html, that link (which is actually to http://somedomain.com/somesite/contact-us.html) will show up in our browser as if it's coming from http://proj1.dev/contact-us.html.

    Again, note that the URL must end in a trailing slash!

    Do note that if there are absolute paths on the target site, even if they are internal to http://somedomain.com/somesite, the address bar will change to reflect the "real" URL.

  6. </VirtualHost>

    This just says, "okay, we're done telling you what to do with this server name."

You'll need a block like this for each of your host names, corresponding to whatever you just put in the hosts file.

Restart Apache

Restart Apache and test by going to one of your new domains!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment