Apache: Don't apply RewriteRule if requested host is a IP address - apache

How doesn't Apache apply an RewriteRule if the requests isn't the normal domain name but instead the server IP?
Current rules (to make domain just accessible without the www):
RewriteEngine On
RewriteCond %{HTTP_HOST} !^domain.com$ [NC]
RewriteRule ^(.*)$ http://domain.com/$1 [L,R=301]
I tried already to add RewriteCond %{HTTP_HOST} !^123.321.123.321$ [OR] but it seemed not to work.

If you have access to the server config file, this works for me (setting it in httpd.conf):
<Location />
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} !^123.123.123.123$
RewriteRule (.*) http://www.mainsite.example.com/ [L]
</Location>
If I visit the site by IP address, it isn't rewritten. If I use (eg.) http://mainsite.example.com, the address is rewritten (to include the www.). The [L] (when used in httpd.conf) stops rewrite processing there (instead of now trying to rewrite the new address).
In there you can also have
ServerName www.mainsite.example.com
ServerAlias mainsite.example.com
ServerAlias www.mainsite
ServerAlias mainsite
ServerAlias 123.123.123.123
so that people can use any of those addresses (the 2nd and 3rd aliases let internal users omit the domain), instead of rewriting to force or add www.

Related

Redirect https://www.website.com to https://website.com not working

I make following post on redirection of https://www.website.com to https://website.com :
Issue with Let's Encrypt certificate : https://www.website.com not working with redirection to https://website.com
I can't get to achieve this redirection and I don't understand what is the reason.
If I type https://www.website.com, it remains on https://www.website.com and doesn't perform the redirection to https://website.com.
My config is a little special with a Zope server working with Apache2.
For the moment, here below are my rewrite rules (http://www.website.com and http//website.com are both redirected fine to https://website.com) :
<VirtualHost *:443>
# REWRITE to get https://www.website.com to https://website.com except for cgi-bin scripts
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/cgi-bin/search [NC]
RewriteCond %{REQUEST_URI} !^/cgi-bin/awstats [NC]
RewriteRule ^/(.*) https://localhost:8443/++vh++https:%{SERVER_NAME}:443/++/$1 [P,L]
</VirtualHost>
<VirtualHost *:80>
<IfModule mod_rewrite.c>
# www to non www for HTTP and HTTPS
RewriteCond %{REQUEST_URI} ^/www\. [NC,OR]
RewriteCond %{REQUEST_URI} !^/podcast [NC]
# Rewrite below works : redirect 80 => https
RewriteRule ^/(.*) https://website.com/$1 [R=301,L]
RewriteRule ^/(.*) http://localhost:9674/++vh++http:%{SERVER_NAME}:80/++/$1 [P,L]
</IfModule>
</VirtualHost>
What could be wrong here?
I believe there are few things of note:
One or more RewriteCond can precede a RewriteRule directive. The following rule is then only used if both the current state of the URI matches its pattern, and if these conditions are met.
The RewriteRule directive......can occur more than once, with each instance defining a single rewrite rule. The order in which these rules are defined is important - this is the order in which they will be applied at run-time.
In VirtualHost context, The Pattern will initially be matched against the part of the URL after the hostname and port, and before the query string (e.g. "/app1/index.html"). This is the (%-decoded) URL-path.
If you wish to match against the hostname, port, or query string, use a RewriteCond with the %{HTTP_HOST}, %{SERVER_PORT}, or %{QUERY_STRING} variables respectively.
You also make use of L|last flags, which makes the engine stop processing further rules after RewriteRule is run.
The above sorta gives you an idea how the engine runs your rewrites:
RewriteRules are processed sequentially (unless you specify L flag, which you do for all rules)
Each RewriteRule can have many RewriteCond which all must match before RewriteRule is considered. It also means that RewriteCond must be repeated for each RewriteRule individually (there's however an interesting technique to group RewriteRules into if-then-else blocks)
In your case (VirtualHost context), only the URL-paths are matched by default unless you manually match HTTP_HOST variable.
With this in mind, I see a few issues with your rewrite rules (I swapped http and https vhosts around for readability but it does not matter):
<VirtualHost *:80> <!-- your http:// requests will end up with this block, because 80 is the port for http -->
<IfModule mod_rewrite.c>
# www to non www for HTTP and HTTPS <!-- I believe HTTPS traffic is NOT handled by this vhost at all, it arrives straight to *:443 queue -->
RewriteCond %{REQUEST_URI} ^/www\. [NC,OR] <!-- you evaluate path component of your request uri to begin with "www." (i.e. /www.index.html) - this will obviously never match, you however have OR flag, which proceeds to the second condition -->
RewriteCond %{REQUEST_URI} !^/podcast [NC] <!-- you check if the path does not start with "/podcast" - this is easy to test - try http://www.website.com/podcast and see if you get redirected to HTTPS - I suspect you will not -->
# Rewrite below works : redirect 80 => https <!-- I suspect it works by accident, please test it out with http://www.website.com/podcast to confirm my theory -->
RewriteRule ^/(.*) https://website.com/$1 [R=301,L] <!-- we end up here, and regardless of the requested path we issue a 301 redirect to https version of the website. This is marked as Last rule, so the engine should stop processing here -->
RewriteRule ^/(.*) http://localhost:9674/++vh++http:%{SERVER_NAME}:80/++/$1 [P,L] <!-- this I believe kicks in when you request a "/podcast" path - this will proxy the request to your http://localhost:9674/ -->
</IfModule>
</VirtualHost>
<VirtualHost *:443><!-- this is where your 301 redirect will com after bouncing through first set of rules above -->
# REWRITE to get https://www.website.com to https://website.com except for cgi-bin scripts
RewriteEngine On <!-- this is important, keep it on -->
RewriteCond %{REQUEST_URI} !^/cgi-bin/search [NC] <!-- you check whether url path does not contain /cgi-bin/search -->
RewriteCond %{REQUEST_URI} !^/cgi-bin/awstats [NC]<!-- AND does not contain /cgi-bin/awstats-->
RewriteRule ^/(.*) https://localhost:8443/++vh++https:%{SERVER_NAME}:443/++/$1 [P,L]<!-- if both conditions above are met - proxy the request to backend and stop further processing. -->
</VirtualHost>
As far as I see - there's no rule to rewrite https://www.website.com -> https://website.com, the only bit your https rewrite is checking is /cgi-bin
My suggestion would be along the following lines (it's probably not a copy and paste solution, but hopefully you will have gotten the gist):
<VirtualHost *:443>
RewriteEngine On
# www to non www for HTTPS
<!-- checking for the same thing again -->
RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
RewriteRule ^/(.*) https://website.com/$1 [R=301,L] <!-- some people might argue second redirect here is excessive since you already arrived at correct host, but I'd leave this for you to sort out -->
<!-- your /cgi-bin checks can be merged into one regex -->
RewriteCond %{REQUEST_URI} !^/cgi-bin/(search|awstats) [NC]
RewriteRule ^/(.*) https://localhost:8443/++vh++https:%{SERVER_NAME}:443/++/$1 [P,L]
</VirtualHost>
<VirtualHost *:80>
<IfModule mod_rewrite.c>
# www to non www for HTTP
<!-- if you want to keep your `/podcast` on http check it first -->
RewriteCond %{REQUEST_URI} !^/podcast [NC]
RewriteRule ^/(.*) http://localhost:9674/++vh++http:%{SERVER_NAME}:80/++/$1 [P,L]
<!-- everything else will get redirected to https -->
RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
RewriteRule ^/(.*) https://website.com/$1 [R=301,L]
</IfModule>
</VirtualHost>
I had the same problem, for only one website of many that were virtually hosted on a amazon lightsail bitnami implementation.
After commenting out the line
ServerName mywebsite.com:80
In the /opt/bitnami/apache2/conf/httpd.conf file the problem was sovled.

Force to SSL maintaining the URL

I don't have much experience with VHOST and SSL, I tried lot of possibilities but none of them is working.
I have a website with 2 folders:
www.example.com/userpage
www.example.com/adminpage
If I go to www.example.com, my loginsystem automatically redirect to www.example.com/userpage.
If I want to go to the admin section, I have to write manually www.example.com/adminpage.
Now I switched to SSL, and everything is working if I type https://....
But I cannot understand how to force the redirect from http to https.
I wrote this in my apache vhost file:
<VirtualHost *:80>
DocumentRoot "C:/xampp/htdocs"
ServerName example.com
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com
RewriteCond ${HTTPS} !=on
RewriteRule (.*) https://example.com/$1 [R=301,L]
</VirtualHost>
But it's not working.
How can I manage it?
If I write www.example.com/adminpage it have to redirect me to https://www.example.com/adminpage.
Actually it should work for every subfolder, if for example I send an email to a user saying "hey user, please check your account www.example.com/user/check_account.php?userid=14125114
it have to then redirect it to automatically:
https://www.example.com/user/check_account.php?userid=14125114
so it should work for every page and every subfolder.
Thank you for your suggestions
Should be quite simple. Replace this block:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com
RewriteCond ${HTTPS} !=on
RewriteRule (.*) https://example.com/$1 [R=301,L]
With this:
Redirect permanent "/" "https://example.com/"

Apache server config redirect from IP to domain name EC2

I am running an apache webserver on a linux EC2 instance.
The problem is that you can access the server using the IP address, DNS and the domain name. This causes a problem for SEO and I want to tidy it up.
I have read on the apache documentation that you can do a mod_rewrite and this needs to be done in the httpd.conf if you have root access otherwise in the .htaccess for per directory override.
I have root access so I am trying to change the httpd.conf
If the user types in
http://52.17.12.123/
or
http://ec2-52.17.12.123.eu-west-1.compute.amazonaws.com/
I want them to be redirected to
www.example.com
This is what I tried
<VirtualHost *:80>
DocumentRoot "/var/www/html/my-website"
# Other directives here
RewriteEngine On
RewriteCond %{HTTP_HOST} !^52.17.12.123.com$
RewriteRule /* http://www.example.com/ [R]
</VirtualHost>
It seems to partially work but www.example.com does not load due to to many redirects.
--EDIT--
Thanks, so now in my httpd.conf I now have the following configuration
Listen 80
NameVirtualHost *:80
DocumentRoot "/var/www/html/my-website"
RewriteEngine On
RewriteCond %{HTTP_HOST} !^(www\.example\.com)$ [NC]
RewriteRule ^/(.*)$ http://www.example.com [R=301,L]
It is all working correctly now
It seems to partially work.
I doubt, considering the rule you currently have in your httpd.conf.
You can have it this way
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteRule ^/(.*)$ http://www.example.com/$1 [R=301,L]

Redirect wildcard subdomains to subdirectory, without changing URL in address bar

I've read a lot of questions and answers about this on here but none that seem to solve my specific problem.
I want to redirect any subdomain to the subdirectory to match.
So: x.domain.com would go to domain.com/x, and y.domain.com would go to domain.com/y - But I want to do this without the URL in the address bar changing.
Here's what I have so far:
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} !^(www)\. [NC]
RewriteCond %{HTTP_HOST} ^(.*)\.domain\.com [NC]
RewriteRule ^ /%1 [P,L]
But this takes me to a website redirect loop, with an incorrect address in the URL bar where the subdomain still exists.
For example, x.domain.com takes me to x.domain.com/x and I get a redirect loop error.
I'd be grateful if anyone can point me in the right direction! Nothing I change seems to work...
First of all, make sure that the vhost in the apache configuration is properly configured and all subdomains of domain.com are in the same host configuration (wildcard):
<VirtualHost *:80>
ServerName domain.com
ServerAlias *.domain.com
...
You can get the redirect working with the following htaccess configuration:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(.*)\.domain\.com
RewriteRule ^(.*)$ http://domain.com/%1/$1 [L,NC,QSA]
Now, if you open asd.domain.com it should redirect you to domain.com/asd.
You will still have the problem, that the redirect is visible in the URL address bar. In order to prevent this, enable mod_proxy (and load the submodules) on your server and exchange the "L" flag with the "P" flag:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(.*)\.domain\.com
RewriteRule ^(.*)$ http://domain.com/%1/$1 [P,NC,QSA]
If this doesn't work, viewing the vhost configuration and the content of error.log on subdomain calling will be helpful!
References:
.htaccess rewrite subdomain to directory
http://httpd.apache.org/docs/2.2/mod/mod_proxy.html
http://httpd.apache.org/docs/2.2/rewrite/flags.html#flag_p
This can be achieved in .htaccess without mod_proxy provided your server is configured to allow wildcard subdomains. (I achieved that in JustHost by creating a subomain manually named *). Add this to your .htaccess file:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.website\.com$
RewriteCond %{HTTP_HOST} ^(\w+)\.website\.com$
RewriteCond %{REQUEST_URI}:%1 !^/([^/]+)/([^:]*):\1
RewriteRule ^(.*)$ /%1/$1 [QSA]
I named the subdirectories under $_SERVER['DOCUMENT_ROOT'] match with my subdomains like so:
/
var/
www/
html/
.htaccess
subdomain1.domain.com/
subdomain2.domain.com/
subdomain3.domain.com/
Where /var/www/html stand as 'DOCUMENT_ROOT'. Then put following code in the .htaccess file:
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/%{HTTP_HOST}/
RewriteRule (.*) /%{HTTP_HOST}/$1 [L]
It works as redirect wildcard subdomains to subdirectories, without changing URL in address bar.
Beside of vhost, you may also put the subdirectories outside root and access it using alias as described here. Then put the same .htaccess code in that location.

Apache alias from sub domain to domains article

I wonder is it possible to make an alias from sub domain, let's say http://sub.domain.com, to http://domain.com/some-article. When user types in address bar sub.domain.com, he should see that article(address in address bar should be the same sub domain, so I think redirect its not what I need). Any ideas?
Your help would be appreciated.
The Apache ServerAlias only covers a hostname and not a fully qualified URI.
In the above example you should use mod_rewrite, making sure to omit the R flag since you don't want to redirect i.e provide a 30X status code in the response.
So in the above example you could have the following
<VirtualHost *:80>
...
ServerName domain.com
ServerAlias sub.domain.com
RewriteCond %{HTTP_HOST} ^domain.com$
RewriteCond %{REQUEST_URI} ^$
RewriteRule ^$ /some-article [L]
RewriteCond %{HTTP_HOST} ^sub.domain.com$
RewriteRule ^(.*) http:/domain.com/some-article$1 [L]
...
</VirtualHost>