在 NGINX 反向代理设置中有效地忽略 cookies 列表

Ignoring cookies list efficiently in NGINX reverse proxy setup

我目前正在 working/testing NGINX 动态内容反向代理设置中的微缓存功能。

发生的一个大问题是 sessions/cookies 需要忽略,否则人们将使用站点上的随机帐户登录。

目前我正在忽略像这样的流行 CMS cookie:

if ($http_cookie ~* "(joomla_[a-zA-Z0-9_]+|userID|wordpress_(?!test_)[a-zA-Z0-9_]+|wp-postpass|wordpress_logged_in_[a-zA-Z0-9]+|comment_author_[a-zA-Z0-9_]+|woocommerce_cart_hash|woocommerce_items_in_cart|wp_woocommerce_session_[a-zA-Z0-9]+|sid_customer_|sid_admin_|PrestaShop-[a-zA-Z0-9]+") 
    {

# set ignore variable to 1
# later used in:
# proxy_no_cache                 $IGNORE_VARIABLE;
# proxy_cache_bypass             $IGNORE_VARIABLE;
# makes sense ?

    }

但是,如果我想将更多 cookie 添加到忽略列表中,这就会成为一个问题。更不用说根据文档不建议在 NGINX 中使用太多 "if" 语句。

我的问题是,这是否可以使用地图方法来完成?我看到地图中的正则表达式不同(或者我错了)。

或者有其他有效 ignore/bypass cookie 的方法吗?

我在 Whosebug 上搜索了很多,虽然有很多不同的例子;我找不到适合我需要的东西。

谢谢

更新:

大量阅读和互联网上的 "digging"(我们不妨只说 Google),我发现了很多有趣的例子。

但是我对这些很困惑,因为我不完全理解正则表达式的用法,我害怕在没有明白了。

示例 1:

map $http_cookie $cache_uid {
  default nil;
  ~SESS[[:alnum:]]+=(?<session_id>[[:alnum:]]+) $session_id;
}
  1. 在这个例子中我可以注意到正则表达式与 "if" 块中使用的那些。我不明白为什么模式 没有任何 "" 开始,直接只有一个 ~ 符号。

  2. 我不明白 [[:alnum:]]+ 是什么意思?我搜索这个 但我找不到文档。 (或者我错过了)

  3. 我看到作者默认设置了"nil",这样就可以了 不适用于我的情况。

示例 2:

map $http_cookie $cache_uid {
  default  '';
  ~SESS[[:alnum:]]+=(?<session_id>[[:graph:]]+)  $session_id;
}
  1. 与示例 1 相同的点,但这次我可以看到 [[:graph:]]+。 那是什么?

我的例子(未测试):

map $http_cookie $bypass_cache {

    "~*wordpress_(?!test_)[a-zA-Z0-9_]+"  1;
    "~*wp-postpass|wordpress_logged_in_[a-zA-Z0-9]+"  1;
    "~*comment_author_[a-zA-Z0-9_]+"  1;
    "~*[a-zA-Z0-9]+_session)"  1;

    default      0;
}

在我的伪示例中,正则表达式一定是错误的,因为我没有找到任何具有此类正则表达式的地图 cookie 示例。

所以我的目标再次是拥有一个地图样式的 cookie 列表,我可以使用适当的正则表达式绕过缓存。

任何advice/examples非常感谢。

你的第二个例子是你真正需要的

map $http_cookie $bypass_cache {

    "~*wordpress_(?!test_)[a-zA-Z0-9_]+"  1;
    "~*wp-postpass|wordpress_logged_in_[a-zA-Z0-9]+"  1;
    "~*comment_author_[a-zA-Z0-9_]+"  1;
    "~*[a-zA-Z0-9]+_session)"  1;

    default      0;
}

基本上这里你所说的 bypass_cache 值将是 1 如果正则表达式匹配 else 0.

所以只要你的模式正确,它就会起作用。而且只有您可以拥有该列表,因为您只知道要绕过哪些 cookie

你到底想做什么?

您这样做的方式是通过 if ($http_cookie … 尝试仅将某些 cookie 列入黑名单以防止缓存,这是一种错误的方法 — 这意味着有一天,有人会发现一个 cookie 不是列入黑名单,您的后端仍然会接受,并导致您缓存中毒或其他安全问题。

也没有理由使用 http://nginx.org/r/map approach to get the values of the individual cookies, either — all of this is already available through the http://nginx.org/r/$cookie_ 范式,使 map 解析出 $http_cookie 的代码相当多余和不必要。

是否有任何您实际想要缓存的 cookie?如果不是,为什么不在存在任何 cookie 时使用 proxy_no_cache $http_cookie; 来禁止缓存?


您可能想要做的是首先确定必须缓存的内容以及在什么情况下必须缓存的内容,然后才求助于用 nginx.conf.[=21= 这样的编程语言来表达此类逻辑。 ]

例如,更好的方法是查看应始终缓存哪些 URL,清除 Cookie header 以确保缓存中毒是不可能的(proxy_set_header Cookie ""; ).否则,如果存在任何 cookie,则可能根本不缓存任何内容(proxy_no_cache $http_cookie;),或者构造缓存以便将某些身份验证凭据组合用于 http://nginx.org/r/proxy_cache_key;在这种情况下,通过 whitelist-based 方法手动重建 Cookie 请求 header 以避免 cache-poisoning 问题也可能是有意义的。