Forum Moderators: phranque

Message Too Old, No Replies

Are my statements correct?

htaccess RegEx

         

guillermo5000

4:55 am on May 10, 2004 (gmt 0)

10+ Year Member



I have read alot of information about Apache and Regexp and think I have a fair understanding, but I have a couple statements in my htaccess that I'm not sure about and perhaps someone could verify that they are doing what I believe they are doing and I'm not sniffing glue.

I wanted to block aaa.xx.****.0 through aaa.xx.****.127 and since it's not a complete range of ip's (0-255), I wrote this:

SetEnvIf Remote_Addr "^aaa.xx.xxx.[0-127]$" ban

If I did want to block the whole class c range I would of used this sub mask:

Deny From aaa.xxx.xx.0/24

I also wanted to block xxx.xx.xxx.0 through xxx.xx.xxx.95 so I used the "SetEnvIf" method below:

SetEnvIf Remote_Addr "^bbb.xx.xxx.[0-95]$" ban

The statements above was, of course accompanied by a "deny from env=ban" statement between my <Limit> tags.

Are these correct?

Thanks for any help!

gergoe

10:18 am on May 10, 2004 (gmt 0)

10+ Year Member



not realy;

the [0-127] means match everything between 0 and 1, and 2 and 7 also, not every number between 0 and 127. if you want to have such a regex, then use [0-9]{1,3}. the same applies to the pattern in your second setenvif directive.

by the way, the first one can be replaced by a simple deny directive: x.x.x.0/25
the second one is a bit more difficult, since this is not a standard subnet range, but you can replace this one also, but with three deny directives:
z.z.z.0/27
z.z.z.32/27
z.z.z.64/27

jdMorgan

7:59 pm on May 10, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



guillermo5000,

When using regular expressions, it's important to remember that that you are comparing characters - not numbers, not meanings, just characters. Regular expressions does define a "numeric character range" as alluded to above. That is, [0-9] means "any character in the range of character "0" to character "9".

So, you can define the IP ranges you want to match as strings, and test them that way if you don't want to use the netmask format.

For example, to match 192.168.0.0-127, you could use:


RewriteCond %{REMOTE_ADDR} ^192\.168\.0\.([0-9]¦[1-9][0-9]¦1[01][0-9]¦12[0-7])$

This breaks down to: 192.168.0. 0-9 or 10-99 or 100-119 or 120-127.

For 192.168.0.0-95, you could use:


RewriteCond %{REMOTE_ADDR} ^192\.168\.0\.([0-9]¦[1-8][0-9]¦9[0-5])$

which breaks down to 192.168.0. 0-9 or 10-89 or 90-95.

The CIDR method, available with mod_access, allows you to specify a subnet mask by specifying the number of ones in the netmask, starting at the highest-order bit (on the left).

For example, to block 192.168.0.0-127, you would convert the lowest and highest address of that range to 32-bit binary numbers:
1100 0000 . 1010 1000 . 0000 0000 . 0000 0000
1100 0000 . 1010 1000 . 0000 0000 . 0111 1111
and then count the number of ones, starting at the left, than will change within this range (bolded digits). In this case, the number would be 25.

So, the CIDR specification would be 192.168.0.0/25

For the case of 192.168.0.0-95. we would have:

1100 0000 . 1010 1000 . 0000 0000 . 0000 0000
1100 0000 . 1010 1000 . 0000 0000 . 0101 1111

However, in this case, the number range requires two CIDR's, because it contains a zero below the highest one that will change over the IP address range. This is an indication that the number is not an even power of two, and that it will span two or more CIDR's.

In this case, you'll have to break it down to two ranges; 192.168.0.0-63, and 192.168.0.64-95

1100 0000 . 1010 1000 . 0000 0000 . 0000 0000
1100 0000 . 1010 1000 . 0000 0000 . 0011 1111
and
1100 0000 . 1010 1000 . 0000 0000 . 0100 0000
1100 0000 . 1010 1000 . 0000 0000 . 0101 1111

This gives two CIDR's:
192.168.0.0/26
192.168.0.64/27

Either way you choose involves complexity, it just depends on which method you prefer.

Jim

[edit] Corrected typo in CIDR binary example [/edit]

guillermo5000

3:13 am on May 11, 2004 (gmt 0)

10+ Year Member



Thank you both!

I don't follow how you arrive at 25 by counting ones?

1100 0000 . 1010 1000 . 0000 0000 . 0000 0000
1100 0000 . 1010 1000 . 0000 0000 . 0111 1111
and then count the number of ones, starting at the left, than will change within this range (bolded digits). In this case, the number would be 25.

jdMorgan

3:23 am on May 11, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



> and then count the number of ones, starting at the left, than will change within this range (bolded digits). In this case, the number would be 25.

Yeah, that wasn't the only error I made, either! :o

Count the number of bits that won't change as the IP varies within the range you want, starting on the left.

Jim

guillermo5000

3:43 am on May 11, 2004 (gmt 0)

10+ Year Member



I see!

So, to use your example, to ban 192.168.0.128-220,
1100 0000 . 1010 1000 . 0000 0000 . 1000 0000
1100 0000 . 1010 1000 . 0000 0000 . 1101 1100
you would use:
deny from 192.168.0.128/25
right?

{{now I'll digest the rest of your very helpful post}}
{{ I see this is incorrect, because it spans two CIDRs as well}}

I would have to use
deny from 192.168.0.128
deny from 192.168.0.129/25

Is that correct?

THANK YOU!

gergoe

10:08 am on May 11, 2004 (gmt 0)

10+ Year Member



personally i'm not much into the calculation of the networks, but if i end up in a situation where i need to use them, i'll use a network calculator, like this one:
[telusplanet.net...]

by the way, the /25 not the one you need, because that covers the second half of the 192.168.0.0 network (192.168.0.128-192.168.0.255)

jdMorgan

1:00 pm on May 11, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



128-220 is a 'sloppy' range - It requires 4 CIDRs; First a 64-address block, which is a /26, then a 16-address block, which is a /28, then 8 addresses with a /29, and finally, four more with /30!

128-224 is easy, that's just a /26 followed by a /27.

Jim