.htaccess restrict ip to url - apache

Im trying to restrict access to the /admin path (Not actual directory) on my web server to a set of IP address'. Here's what i have now, however it doesnt seem to set function as expected.
This is for Craft CMS, below is my .htaccess file sitting in /public_html.
<IfModule mod_rewrite.c>
RewriteEngine On
SetEnv HTTP_MOD_REWRITE On
RewriteCond %{HTTPS} on
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Send would-be 404 requests to Craft
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
RewriteRule (.+) index.php?p=$1 [QSA,L]
RewriteCond %{REQUEST_URI} ^/admin
RewriteCond %{REMOTE_ADDR} !^10.6.
RewriteCond %{REMOTE_ADDR} !^192.168.
RewriteCond %{REMOTE_ADDR} !^172.17.
RewriteRule (.*) / [R=301,L]
</IfModule>

Related

Is there any way to use If..Then..Else in .htaccess on Apache 2.2.29 on Shared Hosting Environment?

I learnt from this Q&A: How to write "if...else" mod_rewrite statements in .htaccess that it is possible to implement If statement in .htaccess but on Apache 2.4 and above.
I learnt from this Q&A: htaccess if statement, how to ipmlement If statement for Apache less than 2.4 versions. The answer by #julp almost solves my problem, but I don’t think I am allowed to do the “appending thing” on Shared Hosting.
Is there any workaround to using If..Then..Else in .htaccess on Apache 2.2.29 on Shared Hosting Environment?
Update:
As instructed by #Thakkie, I am adding my specific requirements.
I am trying to host two domains from one shared hosting account. My .htaccess file is as follows:
<If “%{HTTP_HOST} == ‘domain2.com’”>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ domain2.com-directory/domain2-index.php [QSA,L]
</IfModule>
</If>
<Else>
RequestHeader set X-Prerender-Token "<MyToken>"
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTP_HOST} ^www.domain1.com/domain1-index.php$ [NC]
RewriteRule ^(.*)$ https://www.domain1.com/domain1-index.php$1 [R=301,L]
<IfModule mod_proxy_http.c>
RewriteCond %{HTTP_USER_AGENT} baiduspider|facebookexternalhit|twitterbot|rogerbot|linkedinbot|embedly|quora\ link\ preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator [NC,OR]
RewriteCond %{QUERY_STRING} _escaped_fragment_
# Only proxy the request to Prerender if its a request for HTML
RewriteRule ^(?!.*?(\.js|\.css|\.xml|\.less|\.png|\.jpg|\.jpeg|\.gif|\.pdf|\.doc|\.txt|\.ico|\.rss|\.zip|\.mp3|\.rar|\.exe|\.wmv|\.doc|\.avi|\.ppt|\.mpg|\.mpeg|\.tif|\.wav|\.mov|\.psd|\.ai|\.xls|\.mp4|\.m4a|\.swf|\.dat|\.dmg|\.iso|\.flv|\.m4v|\.torrent|\.ttf|\.woff))(.*) http://service.prerender.io/https://%{HTTP_HOST}/$2 [P,L]
</IfModule>
# Transfers to www.domain1.com when domain1.com is entered
RewriteCond %{HTTP_HOST} ^domain1.com$ [NC]
RewriteRule ^(.*)$ https://www.domain1.com/$1 [L,R=301]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ domain1.com-directory/domain1-index.php [QSA,L]
</Else>
I am assigning one set of operation for domain1.com and another set of operation for domain2.com depending on the HTTP_HOST using <If><Else>.
I tried the above .htaccess file on my friend’s dedicated server, which is running Apache 2.4, and it worked.
But, unfortunately, my shared hosting account provider is running Apache 2.2.29 and thus the <If></If> and <Else></Else> is not supported.
What is the workaround to the <If><Else> in my situation?
This may not be the most perfect solution, but it worked for me.
I was actually using the <If><Else> statement to perform domain specific actions.
As the <If> statement is not allowed in Apache 2.2.29, I appended RewriteCond %{HTTP_HOST} ^domainname.com$ [NC] before every RewriteRule which I wanted to be domain specific.
Thus
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ domain2.com-folder/domain2-index.php [QSA,L]
Becomes
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTP_HOST} ^www.domain2.com$ [NC]
RewriteRule ^ domain2.com-folder/domain2-index.php [QSA,L]
The above lines mean: IF (the requested filename does not exist) AND (the HTTP_HOST is www.domain2.com) THEN use the RewriteRule.
Essentially, I used the RewriteCond to perform the function of the <If> operator, usable in Apache 2.4 or higher.
Now, the entire .htaccess file:
RequestHeader set X-Prerender-Token "<MyToken>"
RewriteEngine On
RewriteCond %{HTTP_HOST} ^domain2.com$ [NC]
RewriteRule ^(.*)$ http://www.domain2.com [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTP_HOST} ^www.domain2.com$ [NC]
RewriteRule ^ domain2.com-folder/domain2-index.php [QSA,L]
# Since I want the HTTPS to be domain specific
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^(domain1.com|www.domain1.com)$ [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTP_HOST} ^www.domain1.com/domain1-index.php$ [NC]
RewriteRule ^(.*)$ https://www.domain1.com/domain1-index.php$1 [R=301,L]
<IfModule mod_proxy_http.c>
RewriteCond %{HTTP_USER_AGENT} baiduspider|facebookexternalhit|twitterbot|rogerbot|linkedinbot|embedly|quora\ link\ preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator [NC,OR]
RewriteCond %{QUERY_STRING} _escaped_fragment_
# Only proxy the request to Prerender if its a request for HTML
RewriteRule ^(?!.*?(\.js|\.css|\.xml|\.less|\.png|\.jpg|\.jpeg|\.gif|\.pdf|\.doc|\.txt|\.ico|\.rss|\.zip|\.mp3|\.rar|\.exe|\.wmv|\.doc|\.avi|\.ppt|\.mpg|\.mpeg|\.tif|\.wav|\.mov|\.psd|\.ai|\.xls|\.mp4|\.m4a|\.swf|\.dat|\.dmg|\.iso|\.flv|\.m4v|\.torrent|\.ttf|\.woff))(.*) http://service.prerender.io/https://%{HTTP_HOST}/$2 [P,L]
</IfModule>
# Transfers to www.domain1.com when domain1.com is entered
RewriteCond %{HTTP_HOST} ^domain1.com$ [NC]
RewriteRule ^(.*)$ https://www.domain1.com/$1 [L,R=301]
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTP_HOST} ^www.domain1.com$ [NC]
RewriteRule ^ domain1.com-folder/domain1-index.php [QSA,L]
P.S. I request the seniors to please rectify my description, if you feel it is inaccurate.

htaccess redirect all but three pages to https

I know this sounds like a duplicate but I have tried as many methods as I can find and I still have not gotten this to work. So please do not auto mark this as a duplicate.
I am trying to redirect all pages of http://www.domian.com to https://www.domain.com with the exception of three pages:/products/product1, /products/product2, /products/product3
I also want those pages to always direct to http since if an https page links to it via a relative link, it will naturally have the https already there.
Also in play is that this is an expression engine site where I am removing the index.php from the URI.
Current Htaccess, which results in those three pages still being https even I go to Http for those pages.
### secure .htaccess file
<Files .htaccess>
order allow,deny
deny from all
</Files>
### EE 404 page for missing pages
ErrorDocument 404 /index.php/site/404
###Block Access to directories with no index file
Options -Indexes
### Simple 404 for missing files
<FilesMatch "(\.jpe?g|gif|png|bmp|css|js|flv)$">
ErrorDocument 404 "File Not Found"
</FilesMatch>
### Although highly unlikely, your host may have +FollowSymLinks enabled at the root level, yet disallow its addition in .htaccess; in which case, adding +FollowSymLinks will break your setup (probably a 500 error), so just remove it, and your rules should work fine.
###Options +FollowSymlinks
RewriteEngine On
RewriteBase /
###Removes index.php from ExpressionEngine URLs
RewriteCond %{THE_REQUEST} ^GET
RewriteCond %{THE_REQUEST} ^[^/]*/index\.php [NC]
RewriteRule ^index\.php(.+) $1 [R=301,L]
### Add the www
RewriteCond %{HTTP_HOST} ^domain\.com
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=permanent,L]
###each option I try I replace in this block as a reference
RewriteCond %{SERVER_PORT} 80
RewriteCond %{HTTPS} !on
RewriteCond %{REQUEST_URI} !^/products/product3
RewriteCond %{REQUEST_URI} !^/products/product1
RewriteCond %{REQUEST_URI} !^/products/product2
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]
######
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
###
Also have tried this which results in the same as above:
RewriteCond %{HTTPS} !on
RewriteCond %{HTTP_HOST} !^(domain\.com/products/product1|domain\.com/products/product2|domain\.com/products/product2) [NC]
RewriteRule ^(.*)$ https://www.domain.com/$1 [R,L]
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^(domain\.com/products/product1|domain\.com/products/product2|domain\.com/products/product2) [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [R,L]
Tried this alone just to see if would be able to navigate to http://www.domain.com/products/product1 and at least not have it rewrite, but it still rewrites to https
RewriteCond %{HTTPS} !on
RewriteCond %{REQUEST_URI} !/products/product1 [NC,OR]
RewriteCond %{REQUEST_URI} !/products/product2 [NC,OR]
RewriteCond %{REQUEST_URI} !/products/product3 [NC,OR]
RewriteRule ^(.*)$ https://www.domain.com/$1 [R,L]
Tried this as well, which again still writes those pages to https. Plus if I try to go to http , it rewrites to https and doesn't remove the index.php
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} !^/products/product3
RewriteCond %{REQUEST_URI} !^/products/product1
RewriteCond %{REQUEST_URI} !^/products/product2
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^/products/product3 http://www.domain.com/products/product3 [R=301,QSA,L,NE]
RewriteRule ^/products/product1 http://www.domain.com/products/product1 [R=301,QSA,L,NE]
RewriteRule ^/products/product2 http://www.domain.com/products/product2 [R=301,QSA,L,NE]
I have honestly tried about 10 -15 versions of all this above and still cannot get it. Including adding index.php? to the request_URI in case that it sees that as part of the request_URI before it's removed. I either end up with the page still rewriting to https or redirect loop land.
Am I missing something simple, is something in the wrong order? I'm just at a loss.
thanks for any help.
UPDATE:
Here's what I used to get it to work:
RewriteCond %{HTTPS} on
RewriteCond %{THE_REQUEST} (\s/products/product1|\s/products/product2|\s/products/product3) [NC]
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [R,L]
RewriteCond %{HTTPS} off
RewriteCond %{THE_REQUEST} !\s/products/product1 [NC]
RewriteCond %{THE_REQUEST} !\s/products/product2 [NC]
RewriteCond %{THE_REQUEST} !\s/products/product3 [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
Here's how we achieved this on a site with a webcam that was in an iframe that wouldn't work on SSL. This was also an ExpressionEngine site.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
#force www instead of non-www
RewriteCond %{HTTP_HOST} ^domain.co.uk
RewriteRule ^(.*)$ http://www.domain.co.uk/$1 [R=301,L]
# HTTP/HTTPS handling
# Force HTTP for webcam page only
RewriteCond %{HTTPS} on
RewriteCond %{THE_REQUEST} \s/webcam-page [NC]
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [R,L]
# Force HTTPS for all pages except webcam
RewriteCond %{HTTPS} off
RewriteCond %{THE_REQUEST} !\s/webcam-page [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
# Removes index.php from ExpressionEngine URLs
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?/$1 [L]
</IfModule>

Redirecting HTTP to HTTPS correctly in Question2Answer script

I have searched for this question for many days and tried so many different methods but nothing works so far. I am using the Question2Answer script and I want to redirect all the HTTP requests to HTTPS.
My URL structure is set to :
/123/why-do-birds-sing (requires htaccess file)
and the htaccess file is as follow:
DirectoryIndex index.php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php?qa-rewrite=$0&%{QUERY_STRING} [L]
RewriteCond %{HTTP:CF-Visitor} '"scheme":"http"'
RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]
</IfModule>
This correctly redirects http://example.com to https://example.com. However, if the user enters an address like this : www.example.com/users they are redirected to https://example.com/index.php?qa-rewrite=users which returns a 404 error.
The index.php?qa-rewrite= is added automatically and removing it from the htaccess totally messes up everything and I think it should be there.
This is because you need all of your redirect rules before any of the routing rules (the ones without the R flag), so:
DirectoryIndex index.php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]
RewriteCond %{HTTP:CF-Visitor} '"scheme":"http"'
RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php?qa-rewrite=$0&%{QUERY_STRING} [L]
</IfModule>
I use this:
DirectoryIndex index.php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-SSL} !on
RewriteCond %{HTTP_HOST} ^example\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com$
RewriteRule ^(.*)$ "https\:\/\/example\.com\/$1" [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php?qa-rewrite=$0&%{QUERY_STRING} [L]
</IfModule>
If you don't like to redirect www, you can remove the line
RewriteCond %{HTTP_HOST} ^www\.example\.com$ and the [OR] above

Remove www as well as add https to a domain name

I'm looking to do the following rewrites:
http://website.com > https://website.com
www.website.com > https://website.com
https://www.website.com > https://website.com
Basically remove www of every combo and redirect everything to https.
Below is the current .htaccess config which seems to solve the first and second one above kind of well but falls apart on the 3rd one. Unable to see what's missing here.
<IfModule mod_rewrite.c>
RewriteEngine On
# remove www if it has it
RewriteCond %{HTTP_HOST} ^www\.
RewriteRule ^(.*)$ http://website.com/$1 [L,R,QSA]
# send everything to https
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-SSL} !on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# BEGIN WordPress
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
</IfModule>
Actually this can be done in a single rule itself:
RewriteEngine On
RewriteBase /
# remove www if it has it
RewriteCond %{HTTP_HOST} ^www\. [NC,OR]
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP:X-Forwarded-SSL} !on
RewriteRule ^ https://website.com%{REQUEST_URI} [L,R=302,NE]
# BEGIN WordPress
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress

.htaccess redirect loop when trying to add forced HTTPS rule (Amazon Elastic Beanstalk)

I started receiving this error after trying to incorporate a rule to force HTTPS in the production environment. The BWC_ENV environment variable can have a handful of different values: "prod", "stage", "ben_local", "nam_local", etc.
Here's my .htaccess:
RewriteEngine On
# Force HTTPS
RewriteCond %{HTTPS} !=on
RewriteCond %{ENV:BWC_ENV} ^prod$
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Parse the subdomain as a variable we can access in our scripts
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTP_HOST} !^www
RewriteCond %{HTTP_HOST} ^([^\.]+)\.([^\.]+)\.([^\.]+)$
RewriteRule ^(.*)$ /$1?subdomain=%1
# Ditto for the path; map all requests to /index.php
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !robots.txt
RewriteRule ^(.*)$ /index.php?path=$1 [L,QSA]
# robots.txt - supply the correct one for each environment
RewriteRule ^robots.txt$ /robots.prod.txt [NC]
RewriteCond %{ENV:BWC_ENV} !prod
RewriteRule ^robots.prod.txt$ /robots.stage.txt [NC]
Edit
What's more, if my .htaccess only contains the following, this will cause a redirect loop too. Why could this be?
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
It turns out this is an Amazon Elastic Load Balancer thing. You have to use Amazon's X-Forwarded-Proto header to accomplish this:
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule !/status https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
You have L flag missing in few rules. Type changing your code to this:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# Force HTTPS
RewriteCond %{HTTPS} !=on
RewriteCond %{ENV:BWC_ENV} ^prod$
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Parse the subdomain as a variable we can access in our scripts
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{QUERY_STRING} !^$
RewriteCond %{HTTP_HOST} !^www
RewriteCond %{HTTP_HOST} ^([^.]+)\.[^.]+\.[^.]+$
RewriteRule ^(.*)$ /$1?subdomain=%1 [L,QSA]
# Ditto for the path; map all requests to /index.php
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !robots.txt
RewriteRule ^(.*)$ /index.php?path=$1 [L,QSA]
# robots.txt - supply the correct one for each environment
RewriteRule ^robots.txt$ /robots.prod.txt [L,NC]
RewriteCond %{ENV:BWC_ENV} !prod
RewriteRule ^robots.prod.txt$ /robots.stage.txt [NC,L]