🔗 功能:重定向助手
- 目标:允许 Squid 按需使用自定义助手来重定向和/或劫持 Web 请求到另一个位置。
- 状态:已完成
- 版本: 2.5+
一些重定向器被恰当地称为 URL 重写器,以反映它们实际所做的工作。即修改正在处理的 URL。由于 Squid 和其他软件(例如 Apache)的悠久历史,存在许多重写器而真正的重定向器很少。
🔗 什么是重定向器?或重写器?
Squid 能够修改请求的 URL。作为外部进程实现,Squid 可以配置为将每个传入的 URL 通过一个助手进程,该进程返回一个新的 URL,或者返回一个空行表示不进行更改。
重定向是 HTTP 的一项定义功能,其中发送状态码在 300 到 399 之间以及替代 URL 到请求的客户端。Squid 中的重定向器助手利用此 HTTP 功能来跳转或重定向客户端浏览器到替代 URL。您可能熟悉 POST 请求或域名之间(例如 www.example.com 和 example.com)的302响应。
重写器不使用此 HTTP 功能,而只是将 URL 改写成新形式。有时这是需要的,但通常不是。HTTP 定义了许多打破此项功能的功能。
助手程序不是 Squid 包的标准部分。但是,下面以及源代码发行版的“helpers/url_rewrite/”目录中提供了一些示例。由于每个人的需求不同,因此需要由管理员自己编写实现。
🔗 为什么要使用重定向器?
重定向器允许管理员控制用户访问的位置。与拦截代理结合使用,可以实现简单但有效的控制。
🔗 它是如何工作的?
助手程序必须从标准输入读取 URL(每行一个),并将重写的 URL 或空行写入标准输出。Squid 在 URL 之后写入额外信息,重定向器可以使用这些信息来做出决策。
从 Squid 接收的输入行
[channel-ID] URL [key-extras]
-
- channel-ID
- 当启用并发时,这是行的 ID。当禁用并发(设置为1)时,此字段以及后面的空格将完全缺失。
-
- URL
- 从客户端接收的 URL。在支持 ICAP 的 Squid 中,这是 ICAP REQMOD 发生后的 URL。
-
- key-extras
- 从 Squid-3.5 开始,传递给助手程序的附加参数可以通过 url_rewrite_extras 配置。为了向后兼容,URL 助手的默认键附加项与 Squid-3.4 及更早版本在此字段位置发送的格式字段匹配:ip/fqdn ident method kv-pair
-
- ip
- 这是客户端的 IP 地址。后面跟着一个斜杠(/),如上所示。
-
- fqdn
- 客户端的 FQDN rDNS(如果已知)。Squid 通常不会执行查找,除非日志记录或 ACL 需要。Squid 不会等待任何结果,除非配置了等待的 ACL。如果不可用,将发送-给帮助程序。
-
- ident
- 客户端机器的 IDENT 协议用户名(如果已知)。Squid 不会等待 IDENT 用户名可知,除非有 ACL 依赖它。因此,在重写器运行时,IDENT 用户名可能尚未可知。如果不可用,将发送-给帮助程序。
-
- method
- HTTP 请求方法。URL 更改,尤其是重定向,仅在某些方法上可能,并且像 POST 和 CONNECT 这样的方法需要特别小心。
-
- kv-pair
- 一个或多个键值对。下面文档中仅定义了“myip”和“myport”对,并且它们由 Squid-3.4 及更早版本无条件发送。
myip=… Squid 接收地址 myport=… Squid 接收端口
🔗 使用 HTTP 重定向器
HTTP 的重定向器功能是“301”、“307”或“302”重定向消息到客户端,指定一个替代 URL 进行处理。
例如;以下脚本可能用于将外部客户端重定向到安全的 Web 服务器以获取内部文档。
$|=1;
while (<>) {
chomp;
@X = split;
$url = $X[1];
if ($url =~ /^http:\/\/internal\.example\.com/) {
$url =~ s/^http/https/;
$url =~ s/internal/secure/;
print $X[0]." 302:$url\n";
} else {
print $X[0]." \n";
}
}
重定向可以通过 url_rewrite_program 接口上的助手来执行。基于每个请求,相同的助手可以生成执行重定向或重写的行。重定向是首选的,因为重写 URL 会给客户端 HTTP 体验带来大量问题。
从 Squid 收到的输入行由上面的部分详细说明。
重定向器以略有不同的格式行返回给 Squid。
返回给 Squid 的结果行
[channel-ID] [result] [kv-pairs] [status:URL]
-
- channel-ID
- 当收到并发channel-ID时,它必须作为行上的第一个条目不变地发送回 Squid。
-
- result
- 其中一个结果代码
OK 成功。出现新 URL。 ERR 成功。此 URL 无操作。 BH 失败。帮助程序遇到问题。
-
- kv-pair
- 一个或多个键值对。在此接口上保留的用于 HTTP 重定向的键名。
clt_conn_tag=… 标记客户端 TCP 连接 (Squid-3.5) message=… reserved status=… 重定向中使用的 HTTP 状态码。必须是以下之一:301、302、303、307、308。 tag=… reserved ttl=… reserved url=… 将客户端重定向到给定的 URL。 *_=… 以 (_) 结尾的键名保留给本地管理员使用。
此辅助程序返回的 kv-pair 可以通过 %note logformat 代码进行日志记录。 -
- status
- HTTP 301、302 或 307 状态码。请参阅 RFC 2616 的 10.3 节,了解 HTTP 重定向码的解释以及它们可以发送的请求方法。
-
- URL
- 要用作替代客户端发送的 URL 的 URL。这必须是一个绝对 URL。即以 http:// 开头或
ftp:// 等。
如果不需要任何操作,请将 status:URL 区域留空。
status 和 URL 之间用冒号 (:) 分隔,如上所示,而不是空格。
🔗 使用重写器在 URL 通过时对其进行修改
通常,重定向器功能用于通知客户端替代 URL。但是,在某些情况下,可能需要重写请求的 URL。然后,Squid 会透明地从 Web 服务器请求新 URL。这可能导致客户端和服务器两端出现许多问题,因此应尽可能避免,而偏向真正的重定向。
一个简单、非常快速的名为 SQUIRM 的重写器是一个不错的起点,它使用 regex 库来实现模式匹配。
一个比 SQUIRM 更快、功能稍多一些的重写器是 jesred。
以下 Perl 脚本也可以用作编写自己的 URL 重写器的模板。
$|=1;
while (<>) {
chomp;
@X = split;
$url = $X[1];
if ($url =~ /^http:\/\/internal\.example\.com/) {
print $X[0]." http://www.example.com/\n";
} else {
print $X[0]." \n";
}
}
URL 重写可以通过 url_rewrite_program、storeurl_rewrite_program 和 location_rewrite_program 接口上的助手来执行。
在 url_rewrite_program 接口上使用时,重写 URL 会给客户端 HTTP 体验带来大量问题。其中一些问题可以通过在 location_rewrite_program 接口上运行的配对助手来缓解,该助手用于反向修改服务器重定向 URL。
返回给 Squid 的结果行
[channel-ID] [result] [kv-pair] [URL]
-
- channel-ID
- 当收到并发channel-ID时,它必须作为行上的第一个条目不变地发送回 Squid。
-
- result
- 其中一个结果代码
OK 成功。出现新 URL。 ERR 成功。此 URL 无更改。 BH 失败。帮助程序遇到问题。
-
- kv-pair
- 一个或多个键=值对。在此接口上为 URL 重写保留的键名称
clt_conn_tag=… 标记客户端 TCP 连接 (Squid-3.5) message=… reserved rewrite-url=… 将事务重写到给定的 URL。 tag=… reserved ttl=… reserved *_=… 以 (_) 结尾的键名保留给本地管理员使用。
此辅助程序返回的 kv-pair 可以通过 %note logformat 代码进行日志记录。
🔗 源服务器的重定向
问题
您正在使用重写器来修改内部 Web 服务看到的 URL。这些不应公开显示。但 Web 服务器仍然会通过重定向将客户端指向这些内部 URL。
通常的 URL 重写器接口仅作用于客户端请求。如果您希望修改服务器生成的重定向(HTTP Location 标头),则必须使用 location_rewrite 助手。
执行此操作的服务器很可能还在使用这些私有 URL,例如在 cookie 或嵌入式页面内容中。Squid 对这些无能为力。更糟的是,您的访问者可能不会以任何方式报告这些问题,表明是重写器造成的。浏览器特有的“我的登录不起作用”只是 cookie 副作用的一个流行示例。
🔗 我可以使用 Perl 以外的其他语言吗?
几乎任何外部脚本都可以用来执行重定向。请参阅 ConfigExamples/PhpRedirectors 以获取使用 PHP 编写复杂重定向器的提示。
🔗 故障排除
🔗 FATAL:所有重定向器已退出!
重定向器进程仅在 *stdin* 关闭时才应退出(停止运行)。如果您看到“所有重定向器已退出”消息,则可能意味着您的重定向器程序存在错误。也许它耗尽了内存或存在内存访问错误。您可能想在 Squid 外部测试您的重定向器程序,使用一个大的输入列表,可能取自您的 *access.log*。此外,请检查重定向器程序的 coredump 文件(请参阅 SquidFaq/TroubleShooting 来确定位置)。
🔗 通道意外回复…
您的 Squid 配置为使用并发,但助手不支持它或返回了损坏的回复。
如果提到的通道包含 **-1**,则助手不支持并发。
如果提到的通道来自重定向器,并且有一个以 301、302 等结尾的大数字。助手不支持并发。
NP:不支持并发的 URL 重写器将无法执行任何重写。
解决方案:将该助手的并发性配置为 **1**。
🔗 重定向器接口损坏,重新 IDENT 值
我添加了一个由以下内容组成的重定向器:
/usr/bin/tee /tmp/squid.log
并且许多重定向器请求在 ident 字段中没有用户名。
Squid 不会延迟请求以等待 ident 查找,除非您使用 ident ACL。因此,很可能在调用重定向器时 ident 不可用,但在请求完成并记录到 access.log 时则变得可用。
如果您想在 ident 查找完成后暂停请求,请尝试执行以下操作。
acl foo ident REQUIRED
http_access allow foo
类别:功能
导航:站点搜索,站点页面,类别,🔼 向上