Nginx 阻止所有具有特定自定义 header 的流量,某些网址除外
Nginx block all traffic with specific custom header except to some urls
我有一个托管在内部网络中的服务,该服务在自定义负载均衡器后面的端口 443(通过 https)接收来自 Internet 和内部网络的流量。
内部网络请求带有一个额外的自定义 header,我们称之为 X-my-lb-header
。
我想阻止所有 uris(return 一个 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,所以我想不出这样做。
有什么想法吗?
所以你需要一些像
这样的逻辑
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
块(也不允许逻辑条件)。虽然有些人发明了一个非常奇怪但有创意的解决方案,比如 this one (emulating AND) or even this one (emulating OR), a huge part of such a problems can be solved using 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; }
我有一个托管在内部网络中的服务,该服务在自定义负载均衡器后面的端口 443(通过 https)接收来自 Internet 和内部网络的流量。
内部网络请求带有一个额外的自定义 header,我们称之为 X-my-lb-header
。
我想阻止所有 uris(return 一个 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,所以我想不出这样做。
有什么想法吗?
所以你需要一些像
这样的逻辑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
块(也不允许逻辑条件)。虽然有些人发明了一个非常奇怪但有创意的解决方案,比如 this one (emulating AND) or even this one (emulating OR), a huge part of such a problems can be solved using 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; }