Squid Web Cache Wiki

Squid Web Cache 文档

🔗 缓存 Windows 更新

作者:Yuri Voinov

🔗 目录

Windows 更新是缓存中最常见的任务之一。

🔗 用法

另一种选择是使用 WSUS 服务器。当出于某些原因无法实现时,您可以使用 Squid 来缓存它。

🔗 Squid 配置文件

像这样粘贴配置文件

# Updates: Windows
refresh_pattern -i windowsupdate.com/.*\.(cab|exe|ms[i|u|f|p]|[ap]sf|wm[v|a]|dat|zip|psf) 43200 80% 129600 reload-into-ims
refresh_pattern -i microsoft.com/.*\.(cab|exe|ms[i|u|f|p]|[ap]sf|wm[v|a]|dat|zip|psf) 43200 80% 129600 reload-into-ims
refresh_pattern -i windows.com/.*\.(cab|exe|ms[i|u|f|p]|[ap]sf|wm[v|a]|dat|zip|psf) 43200 80% 129600 reload-into-ims
refresh_pattern -i microsoft.com.akadns.net/.*\.(cab|exe|ms[i|u|f|p]|[ap]sf|wm[v|a]|dat|zip|psf) 43200 80% 129600 reload-into-ims
refresh_pattern -i deploy.akamaitechnologies.com/.*\.(cab|exe|ms[i|u|f|p]|[ap]sf|wm[v|a]|dat|zip|psf) 43200 80% 129600 reload-into-ims

🔗 故障排除

🔗 如何实现 Windows 更新缓存?

Windows 更新通常(但并非总是)使用 HTTP Range-Offsets(也称为文件部分范围)来并行下载 Microsoft 更新存档的块,或使用随机访问算法来尝试减少网络流量。一些版本的 Squid 仍然不能很好地处理或存储 Range。

需要组合配置选项才能强制缓存范围请求。特别是当涉及大型对象时。

:warning: Windows 8.1 升级包需要缓存高达 5GB 的对象。但是,只要将大小限制设置得足够高,它就能很好地缓存。

:information_source: 由于下面的速度减慢问题,我们建议特殊处理服务包:将最大缓存对象大小扩展到所需大小,然后在单个机器上运行完整下载,然后在一个第二台机器上运行以验证缓存正在被使用。只有在此验证成功后,才通过代理向所有其他机器开放更新。

🔗 防止过早或频繁替换

一旦您完成了上述缓存更新的操作,您就会遇到这样的问题:某些软件经常强制完全重新加载对象,而不是重新验证。这会将缓存的内容推出,并非常频繁地获取新对象。

一个流行的想法是使用 refresh_pattern 正则表达式配置来完成您的 WU 缓存。我决定在我的 squid 代理中测试这个想法,以及一两个其他想法(其他想法都惨败了,但 WU 缓存效果非常好)。

这个想法基本上是这样说的

refresh_pattern microsoft.com/.*\.(cab|exe|ms[i|u|f]|asf|wm[v|a]|dat|zip) 4320 80% 43200

最初的想法在理论上似乎有效,但在实践中却非常没用——更新在 30 分钟后过期,存在下载不一致等一系列问题。因此,查看 HTTP 响应和 refresh_pattern 的文档,发现可以添加一个额外的子句。修改如下:

refresh_pattern -i microsoft.com/.*\.(cab|exe|ms[i|u|f]|[ap]sf|wm[v|a]|dat|zip) 4320 80% 43200 reload-into-ims
refresh_pattern -i windowsupdate.com/.*\.(cab|exe|ms[i|u|f]|[ap]sf|wm[v|a]|dat|zip) 4320 80% 43200 reload-into-ims

现在,这一行告诉我们缓存来自 microsoft.com 的所有 .cab、.exe、.msu、.msu、.msf、.asf、.psf、.wma、……直到 .zip 文件,对象的缓存寿命为 4320 分钟(即 3 天)到 43200 分钟(即 30 天)。下载的每个对象都会被添加到缓存中,然后当一个请求到达时,表明缓存副本不能被使用,它将被转换为 if-modified-since 检查,而不是新的副本重新加载请求。

因此,将其添加到原始的 Squid refresh_pattern 设置中,我们得到:

# Add one of these lines for each of the websites you want to cache.
refresh_pattern -i microsoft.com/.*\.(cab|exe|ms[i|u|f]|[ap]sf|wm[v|a]|dat|zip) 4320 80% 43200 reload-into-ims
refresh_pattern -i windowsupdate.com/.*\.(cab|exe|ms[i|u|f]|[ap]sf|wm[v|a]|dat|zip) 4320 80% 43200 reload-into-ims
refresh_pattern -i windows.com/.*\.(cab|exe|ms[i|u|f]|[ap]sf|wm[v|a]|dat|zip) 4320 80% 43200 reload-into-ims


# DONT MODIFY THESE LINES
refresh_pattern ^ftp:           1440    20%     10080
refresh_pattern ^gopher:        1440    0%      1440
refresh_pattern -i (/cgi-bin/|\?) 0     0%      0
refresh_pattern .               0       20%     4320

这应该可以阻止系统每分钟下载一百万次 Windows 更新。它将分发 Windows 更新,并将其存储在 squid 缓存中。

我还建议分配 30 到 60GB 的 cache_dir 大小,这将允许您下载大量 Windows 更新和其他内容,然后您将不会遇到任何关于缓存存储、缓存分配或其他与缓存相关的问题。

🔗 为什么通过 Squid 如此缓慢?

许多缓存维护人员采用的解决方法是将上述配置设置为,并在范围请求通过时强制 Squid 获取整个对象。

:information_source: 加剧问题并讽刺性地导致一些速度减慢的是,一些 Microsoft 服务器可能会告诉您的 Squid 不要存储存档文件。这意味着 Squid 每次需要任何小块时都会拉取整个存档。

您需要测试您的 squid 配置,并为 range_offset_limit 绕过设置较小的值,看看哪一个能为您提供最佳结果。

尝试强制缓存 Windows 更新时偶尔会出现的另一个症状是服务包。

:information_source: 如果 quick_abort_minquick_abort_maxquick_abort_pct 设置为中止下载不完整,并且客户端关闭时服务包下载量几乎但未达到足够量。随后请求的客户端经常会因等待 Squid 从头开始重新下载整个对象而超时。这自然会导致问题在后续的重新启动尝试中重复出现。

🔗 如何阻止 Squid 为 Windows 更新弹出身份验证框?

将以下内容添加到您的 squid.conf,假设您已将 localnet 定义为您的本地客户端。它**必须**放在任何需要身份验证的 ACL 之前,靠近顶部。

acl windowsupdate dstdomain windowsupdate.microsoft.com
acl windowsupdate dstdomain .update.microsoft.com
acl windowsupdate dstdomain download.windowsupdate.com
acl windowsupdate dstdomain redir.metaservices.microsoft.com
acl windowsupdate dstdomain images.metaservices.microsoft.com
acl windowsupdate dstdomain c.microsoft.com
acl windowsupdate dstdomain www.download.windowsupdate.com
acl windowsupdate dstdomain wustat.windows.com
acl windowsupdate dstdomain crl.microsoft.com
acl windowsupdate dstdomain sls.microsoft.com
acl windowsupdate dstdomain productactivation.one.microsoft.com
acl windowsupdate dstdomain ntservicepack.microsoft.com

acl CONNECT method CONNECT
acl wuCONNECT dstdomain www.update.microsoft.com
acl wuCONNECT dstdomain sls.microsoft.com

http_access allow CONNECT wuCONNECT localnet
http_access allow windowsupdate localnet

上面的配置对于其他自动更新站点(如杀毒软件供应商)也很有用,只需将它们的域添加到 acl 即可。

:information_source: 如果您有 Squid 在 localhost 端口上监听,并且前面有其他软件(例如 dansGuardian),您可能需要为 localhost 地址添加权限,以便前端服务可以中继请求。

...
http_access allow CONNECT wuCONNECT localnet
http_access allow CONNECT wuCONNECT localhost
http_access allow windowsupdate localnet
http_access allow windowsupdate localhost

🔗 Windows Update v5 的 Squid 问题

🔗 AKA,为什么 Internet Explorer 可以正常工作,但后台自动更新失败?

Microsoft Windows 访问 Windows Update 网站似乎存在一些问题。当您通过防火墙阻止所有流量并强制用户通过代理时,尤其是个问题。

症状:Windows 更新给出错误代码,如 0x80072EFD,无法更新,自动更新也无法正常工作。

原因:在早期 Windows 版本中,Windows 更新从 Internet Explorer 获取代理设置。自 XP SP2 以来,这一点不再确定。在我运行 Windows XP SP1 的机器上,没有 Windows 更新问题。当我升级到 SP2 时,Windows 更新在搜索更新等方面开始出现错误。

问题在于 WU 没有通过代理,而是尝试与更新服务器建立直接 HTTP 连接。即使我重新设置了 IE 中的代理,也无济于事。这不是 Squid 的问题,导致 Windows 更新无法正常工作,而是 Windows 本身的问题。解决方案是使用 Windows 附带的 'proxycfg' 或 'netsh' 工具。使用此工具,您可以为 WinHTTP 设置代理。

:information_source: 在同一 Windows 版本中,其他 Microsoft 产品也发现了类似问题。下面的命令通常可以一次性修复所有 Microsoft 代理问题。

🔗 使用 proxycfg 进行代理配置

:information_source: 在 Windows Vista、Server 2008 及更高版本中,proxycfg 已废弃。请改用 netsh。

命令

C:\> proxycfg
# gives information about the current connection type. Note: 'Direct Connection' does not force WU to bypass proxy

C:\> proxycfg -d
# Set Direct Connection

C:\> proxycfg -p wu-proxy.lan:8080
# Set Proxy to use with Windows Update to wu-proxy.lan, port 8080

C:\> proxycfg -u
# Set proxy to Internet Explorer settings.

🔗 使用 netsh 进行代理配置

语法

netsh winhttp set proxy ProxyName:80 "<local>"

C:\> netsh winhttp set proxy 192.168.1.100:3128 "localhost;192.168.1.100"

要重置 WinHTTP 的代理设置,请使用:

C:\> netsh winhttp reset proxy

🔗 Squid 与 SSL-Bump 和 Windows 更新

在现代的 Squid 设置中,Windows Update 无法通过错误“WindowsUpdate_80072F8F”或类似错误来检查更新。

WU 现在使用自己的固定 SSL 证书,并且必须进行拼接才能工作。当您使用嗅探器时,可以看到许多具有相对大子网的 IP 地址。这会导致 Squid-3.4 出现问题,并在使用 Squid-3.5 或更高版本时导致严重问题。

要使用拼接,您需要知道服务器的名称,但递归 DNS 查询不会给出结果。

要使 WU 检查通过 Squid 拼接,您只需要拼接以下 MS 服务器:

update.microsoft.com
update.microsoft.com.akadns.net

在实际设置中使用,请编写 url.nobump 文件。

# WU (Squid 3.5.x and above with SSL Bump)
# Only this sites must be spliced.
update\.microsoft\.com
update\.microsoft\.com\.akadns\.net

只需按如下方式将此文件添加为 Squid ACL:

acl DiscoverSNIHost at_step SslBump1
acl NoSSLIntercept ssl::server_name_regex -i "/usr/local/squid/etc/url.nobump"
ssl_bump splice NoSSLIntercept
ssl_bump peek DiscoverSNIHost
ssl_bump bump all

这样您就不需要知道所有更新的 IP 授权服务器。

:information_source: **注意:** 在某些国家/地区,WU 可能会通过 Akamai 产生 SQUID_X509_V_ERR_DOMAIN_MISMATCH 错误。要进行 WU,您可能需要在 Squid 配置中添加此项:

    acl BrokenButTrustedServers dstdomain "/usr/local/squid/etc/dstdom.broken"
    acl DomainMismatch ssl_error SQUID_X509_V_ERR_DOMAIN_MISMATCH
    sslproxy_cert_error allow BrokenButTrustedServers DomainMismatch
    sslproxy_cert_error deny all

and add this to **dstdom.broken**:

    download.microsoft.com
    update.microsoft.com
    update.microsoft.com.akadns.net
    update.microsoft.com.nsatc.net

:information_source: **注意:** 根据您的 Squid 配置,您可能需要将您的 Squid 的密码套件配置更改为以下之一:

    sslproxy_cipher HIGH:MEDIUM:RC4:3DES:!aNULL:!eNULL:!LOW:!MD5:!EXP:!PSK:!SRP:!DSS

and add this one to your bumped port's configuration:

    cipher=HIGH:MEDIUM:RC4:3DES:!aNULL:!eNULL:!LOW:!MD5:!EXP:!PSK:!SRP:!DSS

3DES and RC4 required to connect to WU and - **attention!** - Skype
assets site.

:warning: 上面的拼接会导致某些更新无法缓存。请注意!

:warning: 添加 3DES,特别是 RC4,会通过客户端和 WU/Skype 以及其他一些网站产生潜在的弱密码。请小心!

Microsoft KB

🔗 OpnSense 使用的 refresh_pattern 示例

https://github.com/opnsense/core/issues/1691#issuecomment-340276788


⚠️ Disclaimer: Any example presented here is provided "as-is" with no support
or guarantee of suitability. If you have any further questions about
these examples please email the squid-users mailing list.

回到 FAQ 索引

类别: ConfigExample

导航: 站内搜索, 站点页面, 类别, 🔼 向上