我推荐使用 Apache 的 RewriteMap 指令。请注意,要使用 RewriteMap 指令,您必须将该指令放在 httpd.conf 而不是 .htaccess 文件中。您可以通过几种简单的方式使用它。
纯文本文件
纯文本版本允许您拥有一个包含 IP 地址的 .txt 文件。我添加了一行评论。这种方式不允许自动过期。
httpd.conf
RewriteEngine on
RewriteMap ipmap txt:/path/to/whitelist.txt
RewriteCond ${ipmap:%{REMOTE_ADDR}} !^allow$ [NC]
RewriteRule .* - [F,L]
白名单.txt
# Chris London added this 2013/06/14
127.0.0.1 allow
123.45.67.89 allow # Some other comment
定制程序
使用 RewriteMap 您实际上可以让它运行一个外部程序,但这个程序带有一些警告。我个人没有使用这种方法,尤其是在 PHP 脚本中。我相信,为了使它与 PHP 脚本一起工作,它必须无限期地运行,读取标准输入并写入标准输出。
RewriteEngine on
RewriteLock /path/to/rewrite.lock
Rewritemap ipmap prg:/path/to/executable.php
RewriteCond ${ipmap:%{REMOTE_ADDR}} !^allow$ [NC]
RewriteRule .* - [F,L]
可执行文件.php
#!/usr/bin/php
<?php
$in = fopen('php://stdin', 'r');
$out = fopen('php://stdout', 'r');
while ($ip = fgets($f)) {
// TODO add better logic
if ($ip == '127.0.0.1') {
fwrite(out, 'allow');
} else {
fwrite(out, 'deny');
}
}
fclose($f);
- 使您的重写地图程序尽可能简单。如果程序挂起,它将导致 httpd 无限期地等待来自地图的响应,这反过来又会导致 httpd 停止响应请求。
- 请务必关闭程序中的缓冲。缓冲 I/O 将导致 httpd 等待输出,因此它会挂起。
- 请记住,该程序只有一个副本,在服务器启动时启动。所有请求都需要通过这一瓶颈。如果许多请求必须通过此过程,或者脚本本身非常慢,这可能会导致显着减速。
数据库查询
我还没有使用过这个,但它看起来很整洁。mod_dbd 需要配置为指向正确的数据库才能工作。您有一个获取 IP 地址的 SQL 语句,您可以为到期日期添加过滤器。
RewriteEngine on
RewriteMap ipmap "dbd:SELECT ipaddress FROM rewrite WHERE expiration < TIME() and ipaddress = %s"
RewriteCond ${ipmap:%{REMOTE_ADDR}} !^%{REMOTE_ADDR}$ [NC]
RewriteRule .* - [F,L]
还有其他几种类型,但这些似乎最适合您。就像我之前说的,我之前没有使用过自定义程序或数据库查询,所以我可能说错了。希望这里的另一个用户可能会发现我的错误,所以这些都对你有用。