This is probably the most common wildcard example, still, I needed some googling to find the perfect way to do it. The idea is that the setup
should accept any kind of subdomains (we don't know in the beginning, what subdomains might come), and serve them
from one central scritp. Of course all this without the user seeing what's going on behind the curtains. Let me make it clear with an example:
http://anything.example.com/somesubdir should be served by http://example.com/centralscript.cgi/anything/somesubdirhttp://anotherthing.example.com/ should be served by http://example.com/centralscript.cgi/anotherthingetc.
So, as you see, we have a
centralscript.cgi, which gets the subdomain name and the directories that were called as a parameter. This of course can be a PHP script too, whatever you prefer. Now, one more thing to the specification: www.example.com and the plain example.com
should work as they are now, no centralscript.cgi magic here.
The solution was found at the wonderful webmasterworld forums - as so often.
This topic discusses the exact same problem. I'll go into more details here and include the necessary nameserver configuration too, but I
don't want to take credit for anything here, I would still be struggling without the fine guys at the webmasterworld.
So, first, let's
set up our nameserver (bind9 is my choice, but whatever you use, this should work. I hope at least.), edit the zone file for your example.com domain. First of all, never forget to
update the timestamp of the zone, so start with that, and then insert the following line to the end of your subdomain list:
* A 1.2.3.4Where of course 1.2.3.4 is the IP of your domain name. Restart the nameserver (
/etc/init.d/bind9 restart, or whatever you use), and check your setup with pinging anything.example.com. Provided that the test box uses the same nameserver too, you should get pretty fast response times. If not, maybe you should wait a bit until the domain zone file spreads to your test box - but be prepared for a bit more time than a cup of tea. Anyway, continue, if you can ping any subdomain under example.com - the
nameserver part is done.
Next,
Apache config and the mysterious
rewrite engine. It's a topic worth to master, but honestly, I didn't have the time yet. The explanation of the techniques below can be found at the webmasterworld forums linked above.
So, open up your httpd.conf file, and look for the virtualhost already set up for your main example.com domain. (I won't explain it here how to do that, it's pretty basic.) Side-note: I'm very much against puting this kind of settings to .htaccess files. Only use those, if you absolutely don't have access to the central configuration file - just imagine, the httpd.conf files are loaded once you start the server, but the .htaccess files are loaded
at every request. No need to overload your server without a reason.
First what you have to do is make sure that apache finds the appropriate virtualhost for all your subdomains. Add this line to the virtualhost settings:
ServerAlias *.example.comTo test if it works, restart apache, and go for http://whatever.example.com. You should see your original www.example.com main page, since no special rules are defined yet for this subdomain. If all goes well, open the httpd.conf file again, and paste this code below at the end of the virtualhost config of www.example.com:
# Rewrite <subdomain>.example.com/<path> to
# example.com/centralscript.cgi/<subdomain>/<path>
RewriteEngine On
# Skip rewrite if no hostname or if subdomain is www
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^www\. [NC]
# Extract (required) subdomain (%1), and
# first path element (%3),
# discard port number if present (%2) (in one line!)
RewriteCond %{HTTP_HOST}<>%{REQUEST_URI}
^([^.]+)\.example\.com(:80)?<>/([^/]*) [NC]
# Rewrite only when subdomain not equal to
# first path element (prevents mod_rewrite recursion)
RewriteCond %1<>%3 !^(.*)<>\1$ [NC]
# Rewrite to /subdomain/path
RewriteRule ^(.*) /centralscript.cgi/%1$1 [L]
# Do some logging
RewriteLog "/var/log/apache/rewrite.log"
RewriteLogLevel 9
Of course you'll have to
replace example.com to your main domain,
and centralscript.cgi for your script's name. Restart apache, and check if it works. If not, study the rewrite log set up above, if yes, comment out the two last lines - again, no need to overload the server with some useless logging junk.
I provide you a simple centralscript.cgi to test if the setup works, and also to see how the parameters are passed:
#!/usr/bin/perl
print "Content-type: text/plain\n\n";
print "CGI parameter (PATH_INFO): $ENV{'PATH_INFO'}";
Of course the usual blahblah applies: script should have the x flag, and ExecCGI should be allowed for the directory where it's in.