Apache 2 + mod_rewrite + Subdirectory confusion

Originally my business’ website was set up fine, with the structure being similar to:
/ – Root domain
/accounts/ – CRM
/webmail/ – Webmail access
What I decided to do was create a subdomain, mail.securityfor.us to use instead of /webmail. I’ve also wanted to set up a document resource section for my business, so I created a subdomain docs.securityfor.us. Ultimately I was able to get the subdomains to play nicely with each other, but I was having issues with /accounts/ redirecting to mail.securityfor.us. Then, the fun begins (after the “Continue”)…
Issue #1: Have mail.securityfor.us show correctly
This was an interesting issue due to how the default 000-default config file was set up in through Apache. All of the virtual host directives were set up as *:80, which made things interesting when I decided to have more than just the “www” domain.
With configuring subdomains with ISPConfig I learned one important thing: wildcard virtual hosts are not meant to be if you plan on using subdomains. Instead, you need to have the directive be <VirtualHost [ip]:80>. This was the first thing I had to fix with the config file (easy fix, just replace the “*” with the public IP of the server).
Issue #2: Have the virtual host point to the mail directory
The meat of this virtual host was actually copied from the main domain, so all I had to do was change DocumentRoot and ServerName to reflect the path to the mail application and the subdomain, respectively.
Issue #3: Have the virtual host point docs.securityfor.us to the document directory
A replica solution of issue #2, making the appropriate changes.
Issue #4: Make sure securityfor.us & www.securityfor.us point to the same directory
This was a little bit trickier to solve initially and caused me a lot of headache that I will get into in a second. But, as ServerName is set to www.securityfor.us, a ServerAlias was needed as securityfor.us to ensure both www & non-www requests point to the same directory.
Issue #5: Have /accounts/ use SSL’ed WWW connection
Issue #5.1: Force SSL
Since I’m proud of the SSL certificate I decided to enforce all connections to go through SSL. So from here until different, all of the information will be put in .htaccess inside of the / directory (/var/www/ in this case). To enforce SSL, it’s very simple:
# Force SSL
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.securityfor.us/$1 [R,L]
This says if the connection is on port 80, redirect anything to HTTPS. There’s another (more modern) way to do this, by replacing the RewriteCond line with the following:
RewriteCond %{HTTPS} !on
While its the same thing as above it can be easier to read.
Issue #5.2: Force WWW for all but mail.securityfor.us
For obvious reasons we don’t want mail.securityfor.us to be redirected to www.mail.securityfor.us, so we have to improvise:
# Force www for all but mail
RewriteCond %{HTTP_HOST} !^www\.securityfor\.us
RewriteCond %{HTTP_HOST} !^mail\.securityfor\.us
RewriteRule ^(.*)$ https://www.securityfor.us/$1 [R=301,L]
This one just says if the request is not asking for www.securityfor.us and is not also asking for mail.securityfor.us make it redirect to www.securityfor.us/whatever.
Issue #5.3: Have /accounts/ point correctly
Before I provide the .htaccess code to this, I want to make it clear that issues 2-4 were the cause for this specific issue. The reason being is that initially (after I fixed issue #1), I could access the /accounts/ page if I requested it via www.securityfor.us, but not if by securityfor.us. As such, until I solved issue #4, I kept getting weird results (mail.securityfor.us showing nothing, securityfor.us/accounts/ pointing to docs.securityfor.us, etc…). Once I got to this point though (after fixing issues 2-4), this one was pretty easy:
RewriteCond %{HTTP_HOST} !^www\.securityfor\.us
RewriteCond %{REQUEST_URI} ^/accounts/
RewriteRule ^/accounts/(.*)$ https://www.securityfor.us/accounts/$1 [R,L]
Since www.securityfor.us/accounts/ worked already, I had to ensure non-www was viewable as well. Of course I could’ve just added this after the issue 5.2 fix, but I just decided not to (no real reason not to, and in fact in a high-traffic situation it could improve performance). I also wanted the RewriteRule to work for JUST the accounts subdirectory, so I make sure it’s a condition that /accounts/ is being requested. Then, the final line just forces SSL and WWW to view account information.
Now, I have since resorted back to the old method in regards to mail (no mail.securityfor.us, just a subdirectory for it). But, this has proved to be a valuable lesson for me as I am still getting over the usage of Apache (been using Lighttpd for a good 5 years now for personal use).
 Comment on this Post