Apache重写子网IP范围

11

请问有人能告诉我怎样把以下IP范围(属于Cloudfront)放到mod_rewrite中吗?我想把example.com的非www请求重定向到www.example.com,但不重定向来自以下IP范围的任何IP地址:

54.192.0.0/16
54.230.0.0/16
54.239.128.0/18
54.239.192.0/19
54.240.128.0/18
204.246.164.0/22
204.246.168.0/22
204.246.174.0/23 
204.246.176.0/20 
205.251.192.0/19 
205.251.249.0/24 
205.251.250.0/23 
205.251.252.0/23 
205.251.254.0/24 
216.137.32.0/19 

我使用一个叫做 rgxg 的工具,将上述所有内容从CIDR转换为Regex,并在我的httpd.conf中创建了以下条目:

    RewriteCond %{HTTP_HOST} ^example\.com$ [NC,OR]

    RewriteCond %{HTTP:X-FORWARDED-FOR} !54\.192(\.(25[0-5]|2[0-4][0-9]||1[0-9]{2}|[1-9]?[0-9])){2} 

    RewriteRule ^/(.*)?$ http://www.example.com/$1 [R=301,NC,NE,L]

我已经将所有IP地址范围添加到RewriteCond条目中,但仅包含第一个IP地址范围,因为我不想在这篇文章中混乱。规则似乎不能工作。如果只放一个IP地址,它可以正常工作。

请问有人可以检查并看看我做错了什么吗?

谢谢! -Ma

2个回答

12
如果您正在使用Apache HTTPD 2.4或更高版本,您还可以使用表达式直接将REMOTE_ADDR与CIDR掩码匹配,而无需将它们转换为正则表达式。
简短形式如下:
RewriteCond expr "-R '192.168.1.0/24'"

以下更长的格式也可用,但文档建议它不够高效。
RewriteCond expr "%{REMOTE_ADDR} -ipmatch '192.168.1.0/24'"

4
可以使用RewriteCond expr"!%{REMOTE_ADDR} -ipmatch'192.168.1.0/24'"来否定表达式。 - Pierre-Alexis de Solminihac

9

让我们来看看第一个范围:

54.192.0.0/16

在正则表达式中
54\.192(\.(25[0-5]|2[0-4][0-9]||1[0-9]{2}|[1-9]?[0-9])){2} 

注意双竖线||。如果出现一点错误,这将很难调试,因此我不介意放弃整个东西。

以下内容并非完全精确,因为它将匹配范围内的所有片段,直到999,但重要的是,它捕获了范围内的所有IP地址,而没有其他有效的IP地址。确实如此。

54\.192\.[0-9]{1,3}\.[0-9]{1,3}

这段文字很容易理解,我建议使用它。试一下,如果行得通,其他选项也可以重新审视。

我不确定您如何获取IP地址,但根据上下文,这是另一个选项:

RewriteCond %{REMOTE_ADDR} !^54\.192\.[0-9]{1,3}\.[0-9]{1,3}$

让我们看一些可能的范围:

54.192.0.0/16 => ^54\.192\.[0-9]{1,3}\.[0-9]{1,3}$
54.230.0.0/16 => ^54\.230\.[0-9]{1,3}\.[0-9]{1,3}$
54.239.128.0/18 => ^54\.239\.(?:19[01]|1[3-8][0-9]|12[89])\.[0-9]{1,3}$
54.239.192.0/19 => ^54\.239\.(?:22[0-3]|2[01][0-9]|19[2-9])\.[0-9]{1,3}$
54.240.128.0/18 => ^54\.240\.(?:19[01]|1[3-8][0-9]|12[89])\.[0-9]{1,3}$
204.246.164.0/22 => ^204\.246\.16[4-7]\.[0-9]{1,3}$
204.246.168.0/22 => ^204\.246\.(?:17[01]|16[89])\.[0-9]{1,3}$
204.246.174.0/23  => ^204\.246\.17[45]\.[0-9]{1,3}$
204.246.176.0/20 => ^204\.246\.(?:19[01]|18[0-9]|17[6-9])\.[0-9]{1,3}$
205.251.192.0/19 => ^205\.251\.(?:22[0-3]|2[01][0-9]|19[2-9])\.[0-9]{1,3}$
205.251.249.0/24 => ^205\.251\.249\.[0-9]{1,3}$
205.251.250.0/23 => ^205\.251\.25[01]\.[0-9]{1,3}$
205.251.252.0/23 => ^205\.251\.25[23]\.[0-9]{1,3}$
205.251.254.0/24 =>  ^205\.251\.254\.[0-9]{1,3}$
216.137.32.0/19 => ^216\.137\.(?:6[0-3]|[45][0-9]|3[2-9])\.[0-9]{1,3}$

感谢您的评论。我有点困惑如何创建CIDR的正则表达式版本。对于CIDR 54.239.128.0/18,以下是否准确:RewriteCond %{HTTP:X-FORWARDED-FOR} !=54.239.128.[1-8]{1,3} ? - Ma Diga
谢谢。我无法理解这些正则表达式是如何生成的。这很有帮助。 - Ma Diga
不用谢。这些是由一位同事制作的,他有很酷的工具,但不喜欢分享,尽管他喜欢炫耀它们能做什么。 :) - zx81
我在RewriteCond中添加了所有的正则表达式,但由于来自范围的某些原因,mod_rewrite仍将我重定向到www.example.com。我希望对于这些范围保持调用为example.com。你有什么想法吗? - Ma Diga
使用正则表达式和 ^ $ 锚点指定范围时,我们应该直接使用 !,请尝试使用 RewriteCond %{REMOTE_ADDR} !^54\.192\.[0-9]{1,3}\.[0-9]{1,3}$RewriteCond %{HTTP:X-FORWARDED-FOR} !^54\.192\.[0-9]{1,3}\.[0-9]{1,3}$ - zx81

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接