Forum Moderators: phranque

Message Too Old, No Replies

Successful mod rewrite for multiple subdomains.

Tips for multiple virtual subdomains that I learned from this forum.

         

jdmelton

12:04 am on Feb 13, 2008 (gmt 0)

10+ Year Member



I had some problems to solve on my websites and I was able to solve them from the work of others in this forum. So, I wished to share my learning. And my thanks!

These work for me on Apache 1.3.37 and 2.2.4 on different servers.

1. I have many virtual subdomains and I do not wish to add them all to the vhosts container. My subdomains have directories under the DocumentRoot, but they are numbered, not named. Users type in names, not numbers. So, www.sub1.demo.com or sub1.demo.com or www.demo.com...

2. I want pretty URLs.

3. I want www.sub3.demo.com/ and sub3.demo.com/index.html and Sub3.Demo.com/IndEx.PHP to work.

4. I do not want to affect /cgi-bin/ requests.

5. I control DNS, httpd.conf, and the rest of the server. I prefer not to use .htaccess files.

6. I needed to map text subdomain names to the numbers of their subdirectories. The filestructure:
/home/demo/public_html/sites
/home/demo/public_html/sites/1111
/home/demo/public_html/sites/1112
/home/demo/public_html/sites/1113
...

The steps needed:

A. Add a wildcard subdomain to the DNS server after all other entries.

*.demo.com 14400 IN A 123.456.789.0

B. Create a map file. Mine is like this:
demo.host.map.txt
www 1111
sub1 1112
sub3 1113
....

I put it outside of DocumentRoot like this:
/home/demo/demo.host.map.txt

(It does not have to be outside of DocumentRoot, but where ever it is, it must be reachable and readable by Apache.)

C. Edit the vhost container. One of mine looks something like this:
(Some lines may wrap in this forum.)

<VirtualHost 123.456.789.0:80>
ServerName demo.com
ServerAlias demo.com
ServerAlias *.demo.com
ServerAdmin webmaster@demo.com

DocumentRoot /home/demo/public_html

ScriptAlias /cgi-bin/ /home/demo/cgi-bin/

-- snip irrelevant stuff --

UseCanonicalName off
RewriteEngine on
RewriteMap lowercase int:tolower
RewriteMap sub txt:/home/demo/demo.host.map.txt
RewriteCond %{REQUEST_URI} !^/cgi-bin [NC]
RewriteCond %{HTTP_HOST} !^demo\.com [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?([a-z.-]+)\.demo\.com [NC]
RewriteRule ^/(.*) /home/demo/public_html/sites/${sub:%2¦1111}/${lowercase:$1} [NC,L]

RewriteLog /usr/local/apache/demo.com-rewrite.log
RewriteLogLevel 0
</VirtualHost>

D. Explanation:

UseCanonicalName off -- Return hostname the user typed into their brwoser.

RewriteEngine on -- Turn on the rewrite engine.

RewriteMap lowercase int:tolower -- Create an internal function named lowercase.

RewriteMap sub txt:/home/demo/demo.host.map.txt -- Name of rewrite map is sub and it is a text file located at the path shown.

RewriteCond %{REQUEST_URI} !^/cgi-bin [NC] -- Don't rewrite requests for cgi-bin.

RewriteCond %{HTTP_HOST} !^demo\.com [NC] -- Don't rewrite if the requested servername is demo.com since CSS and other resources are served from there. A note here: I have not enabled indexing on my servers. So, if someone points to a directory that does not have index.html or index.php, they will get a forbidden message. If they look for a file that is not there, they will get a not found message. If they enter demo.com/css/somefile.css and it is there, it will be returned.

RewriteCond %{HTTP_HOST} ^(www\.)?([a-z.-]+)\.demo\.com [NC] -- Accept for rewriting www.something.demo.com or something.demo.com.

RewriteRule ^/(.*) /home/demo/public_html/sites/${sub:%2¦1111}/${lowercase:$1} [NC,L] -- Rewrite using the sub rewrite map. If a match is found, substitute. If no match is found, use the default 1111. Then, use the lowercase function defined above to rewrite the requested resource to all lower case.

RewriteLog /usr/local/apache/demo.com-rewrite.log -- The rewrite log file and its location.

RewriteLogLevel 0 -- Set to an integer number, per the Apache manual, to actually log stuff. Zero turns it off when you are done troubleshooting.

E. There are some flaws here! First, I rewrite www.demo.com to /home/demo/public_html/sites/1111/. This is where the top-level domain web pages are located. There are site-specific reasons for this. To stop this, I could remove www from the map file. The flaw is what happens when someone types in demo.com/ into their browser. It will rightfully, according to my rules, not rewrite. Then Apache looks in DocumentRoot (/home/demo/public_html), not ../sites/1111. I deal with this in the /home/demo/public_html/index.php file. You probably will want to just not get a match with www in the map file.

It took me a long time to get this far, and I want to share it in hopes that it will be useful to others. I got this to work by piecing together several threads located here, reading the manuals, and failing multiple times...

This is working code with the real domain name and IP address, not theoretical.

jdMorgan

2:18 pm on Feb 15, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Very nice, clean code (with the reservations described in your write-up).

Thanks for posting!

Jim