Introduction
The topic of hosting multiple domains and subdomains on the X1 server has been discussed on this thread quite a bit, but no one has put all the pieces together into a single tutorial. So here's my shot at this. The disclaimer is at the end. :) The work here is based on prior contributions by many and especially bluedog and k1ll3rdr4g0n.
Abstract:
This tutorial shows how to use DynSite, eNom, and an Abyss Web Server X1 with a PHP script for hosting numerous domains and subdomains on a single server. Other dynamic IP resolvers could be used. Their configuration is probably similar to the way DynSite works. Likewise, registrars/DNS services other than eNom could be used. Their functionality is usually very similar. My environment is a Windows XP platform with Abyss X1 V2.0.
Limitations:
All hosted websites share the same server environment. To help with website organization, I opted for a heirarchical directory structure. This requires the use of a relative path for locating images and such. So the <BASE HREF="..."> HTML tag must be used in the <head> section of your web pages. A flat directory structure with all webpages in the /htdocs directory would have probably worked, but then it would have been a naming nightmare. There may be other limitations as well.
Overview
Every domain and subdomain that will be hosted by our X1 points at the same IP. There is no need to use multiple IP's, ports or make it any more complicated. When the DNS sends the http traffic to your X1, the target URL is provided and will be parsed by a script running on X1.
In this example, I'll be working with two domains:
domain1.com
domain2.com
And I will also use several subdomains for each of the above root domains. Here are the steps...
1. The DNS (in my case, eNom)
We start by configuring a DNS for directing http trafic to our X1 server. For eNom this is done using a control panel to set the 'Domain Name Host Records.' We also set up the domain so that a remote program is able to login to our domain and set the appropriate host record.
2. The dynamic IP resolver (in my case DynSite)
Next we configure DynSite to login and set the IP of our target host records. Only one record per each domain needs to be dynamically set.
3. The server directory structure
Next we create a directory structure on the X1 server that reflects the domains and subdomains hosted. (This is not a requirement, just makes it easy to write the script and maintain the websites.)
4. The parsing PHP script
Finally, we install the default script on X1's root which will fetch/redirect http traffic requests as desired.
1. The DNS (in my case, eNom)
Configure the host records as follows:
For domain1.com
@ (none) A (Address) 111.222.123.123 //This is your IP address. It's ok if it's dynamic. Just a starting point.
www Cname (Alias) @ //www is just like the root
* Cname (Alias) @ //Catch-all is just like the root.
Then, set the domain access password for this domain1.com. Remember it. You will need it for the dynamic DNS resolver.
Same thing for domain2.com
@ (none) A (Address) 111.222.123.123 //This is your IP address. It's ok if it's dynamic. Just a starting point.
www Cname (Alias) @ //www is just like the root
* Cname (Alias) @ //Catch-all is just like the root.
Then, set the domain access password for this domain2.com. Remember it. You will need it for the dynamic DNS resolver.
Please note, in the above from the // to the end of the line is just a comment not a setting. By configuring only the root IP and aliasing everyting else to the root makes the setup and the configuration of the dynamic IP resolver easier. Notice that the IP for the above two domains is the same, bucause that's your X1 server's IP.
If you need to host some of the subdomains with another server, you would just configure their record appropriately. For example, you might want to send the catch-all someplace else, so it might look like:
* A (Address) 222.123.123.111
or maybe
* URL Redirect
http://allerrors.com/
That's it for the DNS configuration.
2. The dynamic IP resolver (in my case DynSite)
Open the setup dialog box, select the Services tab, expand the 'Dynamic DNS Services' structure and scroll down and select your DNS service. Mine is eNom, Inc.
Click Add and fill out the account form as follows:
Screen Name: domain1.com
Login: domain1.com
check the box, 'This account requires a password'
Password: here fill in the domain access password from the above DNS settings.
Click OK. This creates an account for your DNS service. Next you have to create a host in that account. So select the domain1.com account you just created under eNom (or your DNS service), and click Add. Then fill out the host form (General Tab) as follows:
Screen Name: domain1.com
Host Name:
Domain Name: domain1.com
That's right, the Host Name above is blank. Nothing else needs to be configured so click OK.
OK, that sets up domain1.com for dynamic IP resolution. Now select the DNS service again and Add another account for domain2.com just like for domain1.com. And then select the new domain2.com and add to it the root host domain2.com just like you did for domain1.com.
OK, it's downhill from here.
3. The server directory structure
The script in the next section assumes that all of your domains are hosted from the X1 default /htdocs directory. You must have some default index files set up in your X1 configuration. Mine uses:
index.html
index.htm
index.php
The directory structure I set up is as follows:
/htdocs
/htdocs/domain1.com
/htdocs/domain1.com/www
/htdocs/domain1.com/sub
/htdocs/domain2.com
/htdocs/domain2.com/sub
Notice that in this example, I'll be sending
www.domain2.com traffic to domain2.com page, so I did not set up a directory for /htdocs/domain2.com/www. This was done simply for example.
Each one of the directories represents a hosted domain or subdomain. It must have an index file that is the web page for that domain/subdomain.
You are now ready for the meat and potatoes.
4. The parsing PHP script
The /htdocs directory has a special index.php script file that will parse the incoming browser request and fetch the appropriate webpage. In my example, this webpage is an all in one which fetches pages for other domains and subdomains, if they exist. If they don't, an error message is printed. You should not have any other index pages in /htdocs. You want to make sure the index.php page is the one that loads when a browser arrives here. This php script gets some info from the browser about the browser's desired destination, and the script fetches the index page representing the domain or subdomain that was requestd.
<?php
//My portions of this script are free for all uses, commercial or not. Best success. --Ely
//Start of PHP code to process domain and subdomain names. Note the plural on NAMES!
//get domain entered in browser
$HOST = $_SERVER['HTTP_HOST'];
//Test if this is domain1.com or one of its subdomain.
if (stristr ($HOST, "domain1.com")) { //Use case insensitive 'strstr()' function. Abyss already does a tolower(), but just in case.
//Yes, so switch on the possible domain1.com subdomains.
switch ($HOST) { //In this switch we will process every subdomain and not allow transfer to an error page.
case "domain1.com": //This is the root domain.
//The following 'include()' or 'header()' assume you set up a default index files in the appropriate htdocs subdirectories.
include("http://domain1.com/domain1.com/"); //I like k1ll3rdr4g0n's approach because it doesn't redirect.
//header("Location: /domain1.com/"); //bluedog's re-direct commented out. Works, but I don't like the '302' re-direct.
//Not using 'exit' here because all domains and subs are mapped to a file.
//Exit is at the end of the 'switch' block.
break;
case "www.domain1.com": //The www subdomain.
include("http://domain1.com/domain1.com/www/");
//header("Location: /domain1.com/www/");
break;
case "sub.domain1.com": //Another subdomain. Repeat this structure for all subdomains.
include("http://domain1.com/domain1.com/sub/");
//header("Location: /domain1.com/sub/");
break;
case "misc.domain1.com": //Another subdomain mapped to the 'sub' subdomain.
include("http://domain1.com/domain1.com/sub/");
//header("Location: /domain1.com/sub/");
break;
//All other subdomains of domain1.com get processed here.
default: //Just send them to www
include("http://domain1.com/domain1.com/www/");
//header("Location: /domain1.com/www/");
break;
} //End of switch.
exit; //Need to exit this file here to prevent further processing.
}
// It wasn't the first domain above, so check for the next domain.
if (stristr ($HOST, "domain2.com")) {
//Yes, so switch on the possible domain2.com subdomains.
switch ($HOST) {
case "domain2.com":
include("http://domain2.com/domain2.com/");
//header("Location: /domain2.com/");
exit;
break;
case "www.domain2.com":
include("http://domain2.com/domain2.com/");
//header("Location: /domain2.com/");
exit;
break;
case "sub.domain2.com":
include("http://domain2.com/domain2.com/sub/");
//header("Location: /domain2.com/sub/");
exit;
break;
case "misc.domain2.com":
include("http://domain2.com/domain2.com/www/");
//header("Location: /domain2.com/www/");
exit;
break;
//Unknown subdomain of domain2.com.
default: //This time, let's treat the unknown subdomain as an error.
break;
} //End of switch.
//Default sub of domain2.com does not exit! Just drop out of if{} statement into a web page.
}
//end of host name processing, finally the default page...
//What follows this PHP code is an edited version of Aprelium's default index page.
//End of PHP code.
?>
<HTML>
<HEAD>
<TITLE>Welcome to Abyss Web Server X1</TITLE>
<STYLE type="text/css">
<!--
BODY {
FONT-SIZE: 11px; COLOR: #000000; FONT-FAMILY: geneva, verdana; BACKGROUND-COLOR: #FFFFFF
}
H1 {
FONT-SIZE: 20px
}
A:hover {
COLOR: #ff9900; TEXT-DECORATION: underline
}
-->
</STYLE>
</HEAD>
<BODY bgColor="#ffffff" text="#000000">
<H1 align=center>Welcome to Abyss Web Server X1</H1>
<BR>
<P>
Welcome to our <B>Abyss Web Server</B>! There is no user website configured at:</p>
<p align=center> <?php echo "$HOST" //Scope of the PHP variable extends here. ?>
</P>
<P>
If you think you've reached this page in error and a user website should be configured here,
please e-mail:</p>
<p align=center>webmaster@yourdomain.com
</p>
<br>
<p>
<center>
<b>This website is hosted on a Sony Vaio with Windows XP and it's <i>'Powered by Abyss Web Server'</i>.</b>
</center>
</P>
<hr>
<P>
<CENTER>
Abyss Web Server X1 -
Copyright ?? 2001-2005 Aprelium Technologies - All rights reserved
<BR><BR>
<A HREF="http://www.aprelium.com" ><IMG SRC="pwrabyss.png" ALT="Powered by Abyss Web Server" BORDER=0 WIDTH=88 HEIGHT=31></A>
</center></P>
</BODY></HTML>
Conclusion
This seems to get the job done. When a surfer types a URL of the form: '
http://sub.domain1.com' the appropriate page is fetched and the surfer has the impression she is visiting the domain as entered. But really, with X2 supporting virtual hosts out of the box for less than 60 bucks, it makes me wonder why I put the effort into this. It was a good learning experience, that's for sure. Plus, this can be useful for developers who need to test numerous projects on their personal desktop.
In any case, if anyone finds this useful, that's great. If anyone finds bugs in this tutorial, or suggestions for improvement, please let me know. If this forum let's me edit, I'll come back and fix it. You can post here or e-mail me: ely AT I HAVE ENOUGH SPAM, THANKS 3wheeldrive.com.
Disclaimer
I'm not an expert PHP programmer. In fact I'm not a PHP programmer at all. I've been working on this for the last few days with some difficulty and finally got it to do everything I needed. I thank the ones who posted here before me because I really couldn't have done any of this without their work.
The whole concept of setting the <base > URL makes me queasy and I don't know if it has greater implications and could possibly break some websites. If you know, your comments would be appreciated.
Use this any way you wish and good luck with your websiteS!
[/b]