Reverse-Proxy

在一個或多個(!)反向代理之後通過 X-Forwarded-For 檢查 Varnish ACL

  • February 26, 2017

我讓 Varnish 在反向代理後面執行(在 localhost 上執行,用於 SSL 解除安裝)。代理設置 X-Forwarded-For 標頭,如果標頭已存在,則將其自身添加到其中。

當我進行 ACL 檢查時,我當然想檢查原始客戶端的 IP,而不是我的代理的 IP,所以我不能使用該client.ip欄位。使用stdvmod 我可以執行以下操作:

vcl 4.0;
import std;
sub vcl_recv {
   if (std.ip(regsub(req.http.X-Forwarded-For, ", 127.0.0.1$", ""), "0.0.0.0") ~ my_acl) {
       ...do stuff...
   }
}

換句話說,在執行它std.ip並將其與我的 ACL 進行比較之前,我從標頭中修剪了代理的 IP (127.0.0.1)。這工作正常,除了…

當 X-Forwarded-For 標頭在到達我的代理之前已經設置時,這將失敗。在這種情況下,XFF 標頭包含三個或更多 IP 地址。修剪最後一個仍然會留下不止一個並std.ip對此感到窒息,將請求延遲幾秒鐘,當然也無法檢查 ACL。

在我關閉代理後,我需要確保 XFF 標頭僅包含一個 IP(IPv4 或 IPv6)。這應該是客戶端的 IP。

例如:

X-Forwarded-For: 10.10.1.1, 10.10.2.2, 2001:a031:100a:dead:beef:1234:1234:1234, 127.0.0.1

應該成為

X-Forwarded-For: 2001:a031:100a:dead:beef:1234:1234:1234, 127.0.0.1

由於我不能信任從外部傳入的任何 XFF 標頭,因此我想丟棄除代理看到的客戶端 IP 之外的任何內容。我的代理不支持修改 XFF 標頭,所以我需要在 Varnish 中進行。

當我可以與標題互動時,Varnish 流程中的第一個點是 in vcl_recv(),此時 Varnish 已經將 添加client.ip到列表的末尾。

我希望使用正則表達式將最後兩項(IPv4 或 IPv6)擷取到帶編號的擷取組($1)中,並簡單地將標頭替換為擷取組。像這樣:

vcl 4.0;
import std;
sub vcl_recv {
   set req.http.X-Forwarded-For = regsub(req.http.X-Forwarded-For, "([a-f0-9:.]+, [a-f0-9:.]+)$", "\1");
}

第三個參數(替換正則表達式匹配的字元的字元串)不起作用。生成的標頭與以前完全相同,即使正則表達式僅擷取最後兩個 IP 地址。

除了 XFF 標頭中的最後兩個 IP 地址之外,我如何丟棄其他任何內容?

你的正則表達式似乎很好。我看到的唯一一件事是您要求自行替換該組。

如果您 ^(.*)在正則表達式的開頭添加並將第二個參數替換為\2

set req.http.X-Forwarded-For = regsub(req.http.X-Forwarded-For, "^(.*)([a-f0-9:.]+, [a-f0-9:.]+)$", "\2");

}

話雖如此,我認為更改 XFF 標頭不是一個好主意。添加標頭而不是更改已由中間代理傳輸的刪除資訊應該更標準。

引用自:https://serverfault.com/questions/834527