我有一個托管在內部網路中的服務,該服務在自定義負載均衡器后面的埠 443(通過 https)接收流量,既來自互聯網,也來自內部網路。
內部網路請求帶有一個額外的自定義標頭,我們稱之為X-my-lb-header.
我想阻止所有 uri 的所有外部傳入流量(回傳 http 回應代碼),但某些特定的除外。
例如,假設我想允許到達兩個端點/endpoind1/(前綴匹配)和/endpoint2實際匹配的流量。
實作這種行為的最佳方法是什么?
如果我的理解是正確的,我需要類似的東西(下面不正確的語法)
location = /endpoind2 {
if ($http_x_my_lb_header not exists) {
pass
} else {
return 404
}
... the rest of the directives
}
location ~ / {
if ($http_x_my_lb_header) {
return 404;
}
... the rest of the directives
}
但是由于 nginx 不支持 else,我無法弄清楚要這樣做。
有任何想法嗎?
uj5u.com熱心網友回復:
所以你需要一些邏輯,比如
if (header exists) {
if (request URI isn't whitelisted) {
block the request
}
}
或者換句話說
if ((header exists) AND (request URI isn't whitelisted)) {
block the request
}
好吧,nginx 不允許嵌套if塊(也不允許邏輯條件)。雖然有些人發明了一個非常奇怪但有創意的解決方案,比如這個(模擬 AND)甚至這個(模擬 OR),但使用map塊(一個非常強大的 nginx 功能)可以解決很大一部分這樣的問題。
下面是一個例子:
# get the $block variable using 'X-my-lb-header' value
map $http_x_my_lb_header $block {
# if 'X-my-lb-header doesn't exists, get the value from another map block
'' $endpoint;
# default value (if the 'X-my-lb-header' exists) will be an empty string
# (unless not explicitly defined using 'default' keyword)
}
# get the $endpoint variable using request URI
map $uri $endpoint {
# endpoint1 prefix matching (using regex)
~^/endpoint1 ''; don't block
# endpoint2 exact matching
/endpoint2 ''; don't block
default 1; # block everything other
}
現在你可以在你的服務器塊中使用這個檢查(不要把它放在某個位置,在server背景關系中使用):
if ($block) { return 404; }
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/353628.html
