2

I have a PHP app on Apache2 that is supposed to treat subdomains on the code level.

My goal is to redirect any wildcard subdomain to the main domain's index.php. I do not use .htaccess.

I searched Stack Overflow and also googled for the solution, and could not find one. The virtual host looks like this:

<VirtualHost *:80>
      ServerAdmin [email protected]
      ServerName example.com
      ServerAlias *.example.com
      DocumentRoot /var/www/html/site_admin/public_html
      # Directory path where code exists
        <Directory /var/www/html/site_admin/public_html>
                Options Indexes FollowSymLinks
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>
        ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel error
        CustomLog ${APACHE_LOG_DIR}/example.com.log combined
        RewriteEngine On
        #If the domain (any domain) is not exactly example.com...
        RewriteCond %{HTTP_HOST} !^example\.com$ [NC]
        RewriteRule (.*) http://(.*).example.com [L,R=301,QSA]
        RewriteRule ^.*$ /index.php [NC,L]
</VirtualHost>

When I access the main domain, I can see the website content. However, if I access sub.example.com, I get redirected to %28.%2A%29.example.com.

If I do this in the redirect rule

RewriteEngine On
RewriteCond %{HTTP_HOST} ^(.*)\.website\.com$ [NC]
RewriteRule (.*) http://example.com [L,R=301,QSA]

I get redirected to the example.com when I access sub.example.com

1 Answer 1

1
   #If the domain (any domain) is not exactly website.com...
   RewriteCond %{HTTP_HOST} !^example\.com$ [NC]
   RewriteRule (.*) http://(.*).example.com [L,R=301,QSA]

If you are expecting requests to both the main domain and to subdomains and handling the subdomains in your application then this rule (a canonical redirect) would seem to be entirely redundant? You need to preserve the requested hostname/subdomain. So, just remove it entirely.

OR, perhaps redirect www to non-www only (for the main domain). For example:

 RewriteCond %{HTTP_HOST} ^www\. [NC]
 RewriteRule ^ http://example.com%{REQUEST_URI} [R=301,L]

(I'm assuming www sub-subdomains on the subdomains are not resolvable.)

You will need to clear your browser cache before testing. Preferably test first with 302 (temporary) redirects to avoid potential caching issues.


Aside:

RewriteRule (.*) http://(.*).example.com [L,R=301,QSA]

This rule is not strictly valid anyway. The 2nd argument to the RewriteRule directive is an ordinary string, not a regex. The resulting %28.%2A%29 you are seeing is the literal text (.*) that has simply been URL encoded in the redirect response. You should also have been preserving the requested URL-path through the redirect. This rule removes it.

   <Directory /var/www/html/site_admin/public_html>
           Options Indexes FollowSymLinks
           AllowOverride All
           Order allow,deny
           allow from all

If you "do not use .htaccess" then you probably should not be enabling .htaccess overrides in the server config. ie. Set AllowOverride None here instead.

NB: Order and allow directives are Apache 2.2 directives. If you are using Apache 2.4 (expected) then you should be using Require all granted instead.

RewriteRule ^.*$ /index.php [NC,L]

This rewrites literally everything to /index.php, including requests for any static resources - so these will not be directly accessible. Is that the intention?

You are not using HTTPS?

6
  • thank you for your response @mrwhite . I'm a complete nube with Apache rewrite rules. I do understand that redirecting (.*) http://(.*).example.com is actually forcing the domain to be literally transcoded to URL format. I do understand that RewriteRule ^.*$ /index.php [NC,L] just forces any URL on the server to go to that index.php. I'm still not sure how do I server website.com, sub.website.com, sub1.website.com and sub2.website.com without rewrite rules
    – igalsc
    Dec 19, 2022 at 21:03
  • @igalsc "I'm still not sure how do I server website.com, sub.website.com, sub1.website.com and sub2.website.com without rewrite rules" - What do you mean? You are using a "rewrite rule". (?) Although you don't necessarily need to for a simple front-controller pattern... you can use mod_dir's FallbackResource instead. Are all these hostnames resolving to your site? (You certainly don't need "rewrite rules" to serve the site from the root of each of your hostnames, as there is nothing to rewrite.)
    – MrWhite
    Dec 20, 2022 at 1:17
  • yes, I have "*" CNAME pointing to the "@" for the domain, so all these hostnames are resolving to the website on the DNS level. I will look into FallbackResource, thank you (not related note - why can't I mention you using "@mrwite"?)
    – igalsc
    Dec 20, 2022 at 1:32
  • Tried <VirtualHost *:80> ServerName website.com ServerAlias *.website.com DocumentRoot /var/www/html/site_admin/public_html <Directory /var/www/html/site_admin/public_html> Options Indexes FollowSymLinks AllowOverride All Require all granted allow from all FallbackResource /index.php </Directory> ErrorLog ${APACHE_LOG_DIR}/website.com-error.log LogLevel error CustomLog ${APACHE_LOG_DIR}/website.com.log combined </VirtualHost> not working
    – igalsc
    Dec 20, 2022 at 2:20
  • @igalsc What do you mean by "not working" exactly? What URL are you requesting? What is the response?
    – MrWhite
    Dec 20, 2022 at 8:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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