This question is not the same as How to Block Spam Referrers like darodar.com from Accessing Website? as that question hightlight on how to block a specific referer.
This question is about to block any request with Referer set and give them a 404 error.
RewriteCond %{HTTP_REFERER} .
RewriteRule .* - [F]
Hope that helps.
Try in htaccess:
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://(www\.)?example.com [NC]
RewriteRule ^ - [R=404,L]
The example above returns a 404 not found error for all referers from http://www.example.com , you can change the example.com string to domain.com your desired domain to block their referer.
Related
In short, my website has a single payments page. SSL certificate is installed but is not required apart for that one payments page.
With regards to my .htaccess file - I currently separate my payments page with the following code. I also block visitors from semalt.com. Can't remember exactly why, but I think I was receiving unwanted attention (spam) from them at the time.
What I would like to know is:
is this code still valid 5 years on?
do I need to address canonicalization by directing to either a www or non-www version of mywebsite (importantly without affecting that one important https payments page); is it necessary?
1. Options +FollowSymlinks
2. RewriteEngine On
3. RewriteBase /
4. # RewriteCond %{HTTP_HOST} !^example\.com$ [NC]
5. # RewriteRule .* http://example.com%{REQUEST_URI} [L,R=301]
6.
7. RewriteCond %{HTTPS} off
8. RewriteRule ^payment\.html$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
9.
10. # block visitors referred from semalt.com
11. RewriteEngine on
12. RewriteCond %{HTTP_REFERER} semalt\.com [NC]
13. RewriteRule .* – [F]
14. # End semalt block
15. # block referer spam buttons for website
16. RewriteEngine On
17. RewriteCond %{HTTP_REFERER} buttons\-for\-website\.com
18. RewriteRule ^.* - [F,L]
19. # End buttons for website block
20.
21. ErrorDocument 404 /404.html
The main thing I would address is that you are only redirecting to HTTPS for your payments page. You should be forcing HTTPS for your entire site - everywhere. These days browsers alert users to the fact that they are browsing an insecure connection if on HTTP (Google Chrome states "Not Secure" next to the URL), which doesn't do anything for user trust. This is the main thing that would have changed in the last 5 years - HTTPS is mandatory everywhere.
There is no good reason not to use HTTPS everywhere these days.
Assuming the rest of your site is already HTTPS "ready" (I assume it must be and you aren't sending users back to HTTP from your payment page?!) then change the HTTP to HTTPS redirect to include your entire site:
# HTTP to HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
2) do I need to address canonicalization by directing to either a www or non-www version of mywebsite (importantly without affecting that one important https payments page); is it necessary?
Yes, you should. You already have the directives at the top of your .htaccess file - but they are commented out? You may have already set the rel="canonical" element in the head of your pages, but otherwise, if www and non-www are both available then this is potentially duplicate content (same content available from 2 or more different URLs). You need to decide which: www or non-www? Which do you currently favour? Which (predominantly) is already indexed? Which does your payments page use? (Hopefully, the answer is the same to all the above.)
Also redirect directly to HTTPS as part of this redirect. And this should go before the current HTTP to HTTPS redirect (the same order as currently in your .htaccess file):
# Redirect to non-www
RewriteCond %{HTTP_HOST} !=example.com
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L]
Note that the above www to non-www redirect assumes you are not using any other subdomains. To redirect to www.example.com, just change both instances of example.com.
RewriteCond %{HTTP_REFERER} semalt\.com [NC]
RewriteRule .* – [F]
Ok, if it helps - check your server logs if this is doing anything for you. But change the .* regex to ^ (marginally more efficient). And any blocking directives should be at the very top of the file (you don't want to bother canonicalising these requests).
RewriteCond %{HTTP_REFERER} buttons\-for\-website\.com
RewriteRule ^.* - [F,L]
Again - OK, it helps (does it?!). Optimise the regex as above. No need to backslash escape literal hyphens in the CondPattern (unless they appear in the middle of a character class). The L flag is not required when used with F.
Other notes:
No need to repeat the RewriteEngine On directive.
You do not need the RewriteBase / directive with your current directives.
It's clearer to define your ErrorDocuments at the top of the file.
Summary
Bringing the above points together we have:
Options +FollowSymlinks
ErrorDocument 404 /404.html
RewriteEngine On
# block visitors referred from semalt.com
RewriteCond %{HTTP_REFERER} semalt\.com [NC]
RewriteRule ^ – [F]
# block referer spam buttons for website
RewriteCond %{HTTP_REFERER} buttons-for-website\.com [NC]
RewriteRule ^ - [F]
# Redirect to non-www
RewriteCond %{HTTP_HOST} !=example.com
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L]
# HTTP to HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
How do I force a 404 error through htaccess for URLs that contain "mobile=no"?
This question is not the same as a previously answered question. This one deals with returning a 404 for URLs that contain a certain parameter. In my case, "mobile=no".
RewriteCond %{QUERY_STRING} ^mobile=no$
RewriteRule ^(.*)$ 404.html [R=404,L,NC]
Try this :
RewriteEngine on
RewriteCond %{THE_REQUEST} \?mobile=no [NC]
RewriteRule ^ - [R=404,L]
I need to block all requests to my site if the referrer is equal to, for example, siteb.com UNLESS the URL being requested is equal to mysite.com/pagex/?random-variable
So if the referrer is siteb.com and the URL being requested is anything other than mysite.com/pagex/?random-variable, my .htaccess file should block the request, otherwise it should be allowed through. If the referrer is not siteb.com, nothing should be done.
I've gotten as far as this:
RewriteEngine on
# Options +FollowSymlinks
RewriteCond %{HTTP_REFERER} siteb\.com [NC]
RewriteRule .* - [F]
However that just blocks ALL requests when the referrer is siteb.com. I need to allow requests to mysite.com/pagex/?random-variable when the referrer is siteb.com
You can add one more condition to your rule to allow /pagex/?random-variable:
RewriteEngine on
# Options +FollowSymlinks
RewriteCond %{HTTP_REFERER} siteb\.com [NC]
RewriteCond %{THE_REQUEST} !/pagex?random-variable [NC]
RewriteRule ^ - [F]
I'm trying to rewrite a URL so that it's user/search engine friendly, then 301 redirect the original URL to the new one.
At the moment the posts generate like this:
example.com/blog/post.php?s=nice-post
But I'd like them to look like this:
example.com/blog/nice-post
Here's what I've got so far:
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
RewriteCond %{QUERY_STRING} ^s=(.+)$
RewriteRule post.php /%1? [R=301,L]
RewriteCond %{REQUEST_URI} !post.php
RewriteRule ^([a-zA-Z0-9_-]+)$ post.php?s=$1
Unfortunately, this clashes with the 404 redirect, sending all pages not found to the blank post.php file, and I can't work out why. Is there a better way of approaching the URL rewrite/redirect?
Thanks for having a look :)
Elaborating on tdammers' suggestion about header()
in your post.php, before outputting anything, decide if it's a valid post or not (for example by looking its id up in the database).
if( !$valid ) {
header( 'HTTP/1.0 404 Not Found' );
echo "404";
exit;
}
i.e. if the page was found invalid, PHP sends out a 404 header to the browser to notify it that this is a missing page. Unfortunately, there's no straightforward way to redirect to Apache's default 404 page, so you'll have to output something yourself -- but since you already have a custom 404 page, you may just include() that.
Going to assume you've got these rules in an htaccess file in your /blog/ directory. Try adding a RewriteBase and removing the leading slash from your query string backreference:
RewriteEngine On
RewriteBase /blog/
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
RewriteCond %{QUERY_STRING} ^s=(.+)$
RewriteRule post.php %1? [R=301,L]
RewriteCond %{REQUEST_URI} !post.php
RewriteRule ^([a-zA-Z0-9_-]+)$ post.php?s=$1
Basically, I am trying to work on the front end of a website, but I would like everyone else but myself to be redirected to a construction page if you like. I currently have:
redirect 301 /index.php http://www.domain.com/construction.php
While this works, it works to well, I would like to be able to still see the live site myself, is it possible to exclude everyone but my IP?
Thanks again.
You could do it with mod_rewrite
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{REMOTE_ADDR} !=123.45.67.89
RewriteRule index.php$ /construction.php [R=301,L]
You'll need some conditions before redirecting:
RewriteCond %{REMOTE_ADDR} !=1.3.3.7
RewriteCond %{REQUEST_URI} !=/construction.php
RewriteRule .* /construction.php [L]
Also, to make sure after the lock-out is removed, clients will see the actual page, this solution does not redirect clients permanently (using a 301 redirect), but internally redirects. Substitute 1.3.3.7 for the actual IP address you're using.
If your apache version is 2.4* , You can redirect your visiters to construction page using the following directives in htaccess :
<If "%{REMOTE_ADDR} !='yourIp'">
RedirectMatch ^/((?!construction.php).*)$ /construction.php
</If>
It says if the ip address is not yourIp redirect all requests to /construction.php .
On older versions of apache, you can use the following mod-rewrite based solution :
RewriteEngine on
RewriteCond %{REMOTE_ADDR} !^myIP$
RewriteRule !construction\.php /construction.php [L]
This internally forwords the request to /construction.php if the RewriteCondition meets. You can Replace L with R if you want to see the redirected url in browser address bar.
hi there you could do the following in .htaccess file
RewriteEngine on
# Redirect all except allowed IP
RewriteCond %{REMOTE_ADDR} !^12.345\.678\.901$
RewriteRule /index.php http://www.domain.com/construction.php [R=302,L]
putting your IP instead of 12.345.678.901
If you have a range of IPs you want to exclude from seeing 'under construction' page you can use |
RewriteEngine on
RewriteCond %{REMOTE_ADDR} !^127.0.0.1|212.250.141.228
RewriteRule ! construction\.html /construction.html [R]
It is important to put the 2 last lines at the end of your .htaccess file, especially when it contains more rewriting rules.
The following worked for me
Deny from all
Allow from xxx.xxx.xx.xxx
If you are interested on having a background image referenced on your construction.php, the code below avoids the image to be redirected:
RewriteCond %{REMOTE_ADDR} !=THE_IP
RewriteCond %{REQUEST_URI} !^\/construction\.php|\/YOUR_IMAGE\.jpg
RewriteRule .* /construction.php [R=302,L]
In addition to using the if directive as other answers suggested, you can also add multiple IPs by including other conditions into one directive using the && operator as such:
<If "%{REMOTE_ADDR} != '127.0.0.1' && %{REMOTE_ADDR} != '192.168.1.1'">
RedirectMatch ^/((?!construction.php).*)$ /construction.php
</If>
See the docs here: http://httpd.apache.org/docs/2.4/mod/core.html#if
Another idea is to give access only to a certain range
RewriteEngine on
RewriteBase /
# Validator
SetEnvIf Remote_Addr "^128.30." IsInt
# Local
SetEnvIf Remote_Addr "^192\.168" IsInt
Order allow,deny
Allow from env=IsInt
Not any one worked until I find my own solution
URL in code: http://www.example.com/index_cons.php
IP address in example is: 75.85.95.105
Tested on lastest version of Cpanel.
RewriteEngine on
RewriteCond %{REMOTE_ADDR} !^75\.85\.95\.105
RewriteCond %{HTTP_HOST} ^example\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com$
RewriteRule ^/?$ "http\:\/\/example\.com\/index_cons\.php" [R=302,L]