Is it possible to configure Apache for different virtual hosts based on the source IP? (i.e. same interface, same hostname, but two different virtual hosts, with different content, based on source IP.)

The motivation for this is so that my IP address can access the site proper, but that everyone else gets the holding page. The conventional solution seems to be to use mod_rewrite to direct visitors to a separate page within the same docroot, but I'd like to use a completely different docroot for the holding page instead.

link|improve this question

67% accept rate
BTW, why do you need this logic for yourself on the server? You can map the domain to the IP of a testing server (or your own computer) for just yourself using your hosts file. – Dan Grossman Aug 2 '11 at 10:47
do you have several names to handle or only one? as you can work (define the Virtualhosts) with names Or with IP. – regilero Aug 2 '11 at 11:28
any particular reason why a different doc root? – anthonysomerset Aug 2 '11 at 11:36
The OP's stated rationale doesn't make sense (a holding page works great with a rewrite), but if you were, say, reworking a site, needed a way to host the rework, and didn't know that subdomains existed, you might decide to do it this way. – womble Aug 2 '11 at 11:45
You could use Allow/Deny lines to block access to everyone except you and have a custom error document for 403 errors (Make sure you put it in a directory and allow access to that directory, else the error document will 403 as well), or use rewrite rules/rewrite conditions, or move your pre-launch/testing site to a subdomain like dev.example.com then example.com could have the holding page – sam Aug 2 '11 at 11:46
show 3 more comments
feedback

4 Answers

up vote 2 down vote accepted

I don't know if that's possible (without mod_rewrite, anyway) in Apache level.

Here's another idea. What if you set up two Apache virtual hosts and then use iptables to transparently forward visitor to correct virtual host? Something like

iptables -A PREROUTING -t nat -i eth0 -p tcp -s your.ip.address -d your.server --dport 80 -j DNAT --to-destination your.actual.site:someport
iptables -A PREROUTING -t nat -i eth0 -p tcp ! -s your.ip.address -d your.server --dport 80 -j DNAT --to-destination your.holding.site:someport

Or something similar. :)

link|improve this answer
I'd say this is going to be the least-worst option. – womble Aug 2 '11 at 11:46
feedback

AFAIK, the only way to do this is to symlink a location within the document root to your content outside the document root, then rewrite the request to that.

link|improve this answer
feedback

Here's the answer I posted to the same question on stackoverflow

It wouldn't really be a different virtual host. But using something like mod_rewrite or mod_alias you can serve content out of any folder for which you have set the appropriate permissions. There's only one docroot, but you can effectively change that on the fly.

One way to do it might be:

<VirtualHost *.80>
    ServerName example.com
    ...
    DocumentRoot "/path/to/root"
    <Directory "/path/to/root">
       ...
    </Directory>
    <Directory "/path/to/not/root">
       Order allow,deny
       #replace with your IP
       Allow from 192.168.0.100 
       ...
    </Directory>
    RewriteEngine On
    #Rewrite to alternate path if IP address matches
    RewriteCond %{REMOTE_ADDR} ^192\.168\.0\.100$
    RewriteRule ^/(.*)$ /path/to/not/root/$1
<VirtualHost>

Do note though that it'd probably be a bit cleaner to handle this with a dev subdomain.

link|improve this answer
feedback

It wouldn't really be a different virtual host. But using something like mod_rewrite or mod_alias you can serve content out of any folder for which you have set the appropriate permissions. There's only one docroot, but you can effectively change that on the fly.

One way to do it might be:

<VirtualHost *.80>
    ServerName example.com
    ...
    DocumentRoot "/path/to/root"
    <Directory "/path/to/root">
       ...
    </Directory>
    <Directory "/path/to/not/root">
       Order allow,deny
       #replace with your IP
       Allow from 192.168.0.100 
       ...
    </Directory>
    RewriteEngine On
    #Rewrite to alternate path if IP address matches
    RewriteCond %{REMOTE_ADDR} ^192\.168\.0\.100$
    RewriteRule ^/(.*)$ /path/to/not/root/$1
<VirtualHost>
link|improve this answer
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.