Forum Moderators: phranque

Message Too Old, No Replies

Block IP from accessing a certain page on website

         

Nail_Yener

8:26 am on Dec 14, 2014 (gmt 0)

10+ Year Member



Hi,

I have the following code in my .htaccess file to block an IP from accessing a file on my site and it works fine.

<Files mypage.html>
Order Deny,Allow
Deny from XXX.XXX.XXX.XXX
</Files>


Is there a way to block an IP from accessing a page (e.g., mydomain.com/mypage/)? Thanks for a any ideas.

lucy24

8:56 am on Dec 14, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Is there a way to block an IP from accessing a page

Isn't that what you are already doing? Or did you mean, accessing any and all pages? Change to a FilesMatch such as
<FilesMatch "\.html$">

replacing .html with whatever extension the site uses. That's physical files, not URLs, if they happen to be different.

But I may have misunderstood the question. Do you want to admit certain requests while denying others from the same IP? Otherwise there would be no point to a Files(Match) envelope at all; just leave the Deny from... directive lying loose in htaccess.

Nail_Yener

9:29 am on Dec 14, 2014 (gmt 0)

10+ Year Member



The code I have blocks access to files. Let's assume I have a page using permalink

http://mydomain.com/mypage/


and I want to block access to that. The above permalink is created by rewrite rules.

wilderness

5:55 pm on Dec 14, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I'm sure lucy will correct my syntax errors for you shortly.

RewriteCond %{REMOTE_ADDR} ^123\.456\.789\.
RewriteCond %{REQUEST_URI} MyPage\.html
RewriteRule .* - [F]

lucy24

9:08 pm on Dec 14, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I'm sorry. I don't understand what you want to do that you're not doing already.

<Files> and <FilesMatch> refer to the physical file. (There are exceptions which we need not concern ourselves with here.) If your pages are generated by a CMS, you can't use these forms, because the named file doesn't really exist. That's when you need to go to mod_rewrite-- which your CMS, if any, is already using.

With rare exceptions, anything that can go in a %{REQUEST_URI} condition can and should go in the body of the rule instead:
RewriteCond %{REMOTE_ADDR} ^123\.456\.789\.
RewriteRule ^MyPage\.html - [F]


But the key question is still unanswered, so I will rephrase it:
Do you want to admit certain requests from a particular IP, while denying others from the same IP?

phranque

12:00 am on Dec 15, 2014 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



Let's assume I have a page using permalink

http://mydomain.com/mypage/


and I want to block access to that.

RewriteCond %{REMOTE_ADDR} ^xxx\.xxx\.xxx\.xxx
RewriteRule ^mypage/$ - [F]

Nail_Yener

11:23 am on Dec 15, 2014 (gmt 0)

10+ Year Member



Thank you everyone, this is what I was looking for:

RewriteCond %{REMOTE_ADDR} ^xxx\.xxx\.xxx\.xxx
RewriteRule ^mypage/$ - [F]


I have two questions:

1) I know the reason why a backslash is used, period means any character, but is it really necessary in this case (for an IP)? The following worked just as fine.

RewriteCond %{REMOTE_ADDR} ^xxx.xxx.xxx.xxx
RewriteRule ^mypage/$ - [F]


2) Using this method, is it possible to block an IP range using a CIDR value? For example:

xxx.xxx.xxx.xxx/24


Thanks.

wilderness

3:42 pm on Dec 15, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



1) I know the reason why a backslash is used, period means any character, but is it really necessary in this case (for an IP)? The following worked just as fine.


Absolutely.
You just think it does because it covered your one IP.
It will fail for other IP's (lucy will explain later)


2) Using this method, is it possible to block an IP range using a CIDR value? For example:

xxx.xxx.xxx.xxx/24


NO.
CIDR are not used with mod_rewrite, although I seem to recall some possibility of introduction with Apache 2.4.

This 24 in mod_Rewrite would simply be
^146\.185\.253\.
or (overkill)
146\.185\.253\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-9])$

lucy24

5:18 pm on Dec 15, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The following worked just as fine.

In the specific case of IPs, forms with unescaped . will always "work fine" -- that is, they'll match the intended pattern. The problem is that they may also work where you don't want them to (false positive).

If each part of your IP address happens to have 3 digits-- or 2 digits beginning in [3-9]-- there's no risk of ambiguity. But a form like

^1.2.3.4

without closing anchor will not only match 1.2.3.4. It will also match 102.3.4, 102.3.45, 1.223.40, and so on.

Which requests from this particular IP do you not want to block? And why do you need to convert to mod_rewrite when the rule quoted in the first post works perfectly well?

or (overkill)
146\.185\.253\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-9])$

^146\.185\.253\.\d{1,3}$ ;)
The moment you add a fourth number block, an opening anchor becomes optional for IPs beginning in three digits. But it still makes things more efficient.

wilderness, I tried to pin down the IP/2.4 question, but got sidetracked by the brand-new condition [httpd.apache.org] %{IPV6} (all caps) leaving %{REMOTE_ADDR} for the familiar IPv4. I suspect the CIDR stuff is buried under mod_remoteip. Then again there's the new <If> structure, which can be used in htaccess and may make most things a non-issue.

Nail_Yener

12:50 pm on Dec 16, 2014 (gmt 0)

10+ Year Member



Thank you very much wilderness and lucy24.

I understand now why escaping the dots are a must in that case.

@lucy24, the rule I have in the first post with Files directive, works for files (mypage.html, mypage.php, etc.) but it doesn't work for a rewritten URL like /mypage/. The Rewrite solution you and others provided work for such URLs.

I also learned that I can also use something like

<IF "%{REQUEST_URI} ^/mypage/$">
Require not ip 111.111.111.0/24
</IF>


which seems to fit my purpose better. I assume I don't need to escape dots in this case.

EDIT: I realized that I can't use the IF directive as my server uses Apache 2.2.24, and I believe most servers still don't use 2.4.

lucy24

8:35 pm on Dec 16, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



it doesn't work for a rewritten URL like /mypage

Understood. But the question is: Are there any requests from this particular IP that you do not want to block? If you simply want to lock them out globally, there's absolutely no need for mod_rewrite or <Files> envelopes or anything else; all you need is the
Deny from...

line.

Is this WordPress? As I understand it, WP has an internal (though inefficient) way of handling 404s, but it doesn't have a built-in mechanism for 403s. So you would need a couple of extra lines if you wanted to use a custom 403 page-- which, for the sake of human visitors, everyone should do.

While I was looking things up at Apache, I found some preliminary docs for 2.5, meaning that one of these days there will be a 2.6. But so far I can't think offhand of anyone who has come in with an explicit 2.4 question. Maybe the only people using 2.4 are the ones who have their own servers and speak fluent Apache, so they never need to ask anything.

Nail_Yener

9:08 am on Dec 17, 2014 (gmt 0)

10+ Year Member



Yes, I was trying to block a particular IP (or an IP range) from accessing a single page, but allowing access to the rest of the site.

It's not WordPress.

Sorry, I couldn't understand what you meant in your last paragraph.

lucy24

3:38 pm on Dec 17, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I couldn't understand what you meant

That's OK ;) I was addressing wilderness because we got into the digression on Apache 2.4.