基于referer的nginx条件路由

2023-12-25

我需要根据 http 请求来源路由流量。我有两个环境,我们需要使用“$http_referer”将“/us-en”的每个 http 请求重定向到环境 1,将其他请求重定向到环境 2。

  1. 基于位置的重定向有效。
location ~ /us-en { 
    proxy_pass Environment1; 
    proxy_set_header Host Environment1; 
} 
  1. 对于“$http_referer”,以下选项不起作用。请求您对此提出建议。
if ($http_referer ~ ^https?://dev.xyz.com/us-en){ 
    rewrite ^/us-en(/*)$ HOME_PAGE$1 break; 
    proxy_pass Environment1; 
}
Error: nginx: [emerg] "proxy_pass" directive is not allowed here in /opt/nginx/conf/nginx.conf.

注意:默认情况下,由于存在上游配置,所有流量都会进入环境 2。


    # needed if your proxy destination specified with domain name instead of IP address
    resolver 8.8.8.8;

    location /home/ {
        proxy_set_header Host HOST1;
        # setup other proxied headers if needed
        if ($http_referer ~ ^https?://dev.xyz.com/home) {
            rewrite ^/home(/.*)$ HOME_PAGE$1 break;
            proxy_pass https://HOST1:8080; # this can be specified by IP address
        }
    }

有了这样的配置请求your_domain.com/home/path/file from dev.xyz.com/home/...(但不是来自dev.xyz.com/any/other/path!)将被代理到https://HOST1:8080/HOME_PAGE/path/file。如果您使用域名而不是 IP 地址指定代理目标,则需要指定附加参数resolver http://nginx.org/en/docs/http/ngx_http_core_module.html#resolver在你的服务器配置中。您可以使用本地名称服务器(如果有),也可以使用外部名称服务器,例如 Google 公共 DNS (8.8.8.8) 或 ISP 为您提供的 DNS。无论如何,这样的配置会导致额外的 DNS 查找,因此如果可以的话,请使用 IP 地址指定您的代理目标。

Update

还有另一种方法可以做到这一点valid_referers http://nginx.org/en/docs/http/ngx_http_referer_module.html#valid_referers指示:

    # needed if your proxy destination specified with domain name instead of IP address
    resolver 8.8.8.8;

    location /home/ {
        proxy_set_header Host HOST1;
        # setup other proxied headers if needed
        valid_referers example.com/home;
        if ($invalid_referer = "") {
            rewrite ^/home(/.*)$ HOME_PAGE$1 break;
            proxy_pass https://HOST1:8080; # this can be specified by IP address
        }
    }

更新@2020.11.11

除了这个答案以某种方式获得了 5 分之外,给定的解决方案的设计非常糟糕(在location和嵌套的if堵塞;此外,拥有一个if使用除 nginx 之外的任何指令进行阻止重写模块 http://nginx.org/en/docs/http/ngx_http_rewrite_module.html如果可能的话应该避免)并且在早期的 nginx 版本上根本不起作用(当我看到我的一些早期答案时我想哭)。最初的OP问题是

逻辑应该如下所示,但有一些语法错误。

if ($http_origin ~ '^http?://(dev.xyz.com/home)') {
    set $flag 'true';
}

if ($flag = 'true') {
    location /home/ {
        proxy_pass  "https://HOST1:8080/HOME PAGE/";        
    }
}else{
    Do Not proxy pass
}

目前尚不清楚是什么不代理通过方法。如果这意味着返回一些HTTP错误(例如HTTP 403 Forbidden),可以通过以下配置来完成:

location /home/ {
    if ($http_referer !~ ^https?://dev.xyz.com/home) {
        return 403;
    }
    rewrite ^/home(/.*)$ HOME_PAGE$1 break;
    proxy_set_header Host HOST1;
    # setup other proxied headers if needed
    proxy_pass https://HOST1:8080; # this can be specified by IP address
}

If 不代理通过意味着在本地处理请求,解决方案更复杂:

map $http_referer $loc {
    ~^https?://dev.xyz.com/home    loc_proxy;
    default                        loc_local;
}

server {
    ...
    location /home/ {
        try_files /dev/null @$loc;
    }
    location @loc_proxy {
        rewrite ^/home(/.*)$ HOME_PAGE$1 break;
        proxy_set_header Host HOST1;
        # setup other proxied headers if needed
        proxy_pass https://HOST1:8080;
    }
    location @loc_local {
        rewrite ^/home(/.*)$ HOME_PAGE$1 break;
        root /path/to/required/page;
        ...
    }

The try_files /dev/null @the_named_location;技巧取自this https://serverfault.com/questions/908086/nginx-directly-send-from-location-to-another-named-location/965779#965779很好的答案。

然而,现在编辑后的OP的问题提出了不同的要求,这也可以通过map指令帮助:

map $http_referer $environment {
    ~^https?://dev.xyz.com/home    Environment1;
    default                        Environment2;
}

server {
    ...
    location /home/ {
        rewrite ^/home(/.*)$ HOME_PAGE$1 break;
        proxy_set_header Host $environment;
        # setup other proxied headers if needed
        proxy_pass https://$environment;
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于referer的nginx条件路由 的相关文章

随机推荐

  • 如何检查进程是否属于当前用户?

    我正在尝试获取属于当前用户的进程的 PID 但我不知道如何检查进程所有者 这是我的代码 缺少用户的检查条件 uses TlHelp32 type TCardinalArray array of Cardinal function GetCu
  • 如何在tensorflow.js中获取/设置监督模型的权重?

    我想更改监督模型的权重 但更改权重后得到的结果完全相同 我究竟做错了什么 const model tf sequential model add tf layers dense model add tf layers dense model
  • 我想测试一个私有方法 - 我的设计有问题吗? [复制]

    这个问题在这里已经有答案了 因此 我对软件测试非常陌生 并且正在考虑向我的一个应用程序添加一些测试 我有一个公共方法 addKeywords 它一路上调用一个私有方法removeInvalidOperations 这个私有方法调用外部 AP
  • AngularJs - ngRepeat 带有返回新对象的过滤器

    我正在尝试对过滤器中的对象应用转换 这会导致返回一组新对象 这是因为我想在应用转换后过滤对象并显示转换结果 然而 我最终得到了无限的摘要 因为我显示的对象与我放入的对象不同 当比较它们时 ids 我解决这个问题的想法如下 使用类似的跟踪表达
  • 谷歌地图发布密钥的 SHA1 显示一些加密文本

    我正在使用谷歌地图 在调试模式下 这真是太棒了 对于发布模式 我尝试从我的 windows10 hp probook 获取发布 SHA1 密钥 但我得到了一些加密文本而不是 SHA1 我的命令如下 C Program Files Java
  • GetSupportActionBar 返回 null

    当我开始第二个 Activity 后 就没有 ActionBar 了 当我调用 GetSupportActivity 时 它返回 null 为什么 我有 minSdkVersion 10 和 targetSdkVersion 15
  • 在 Haxe 中传递任意函数参数列表

    在 ActionScript 中我可以使用 在函数声明中 因此它接受任意参数 function foo args void trace args length 然后我可以调用传递数组的函数 foo apply this argsArray
  • JS 中的动态 import() 文件

    我需要导入标记文件动态切片文件的一部分并将结果添加到变量并在我的 React 应用程序中渲染结果 import changelog md then 我试图这样做render 具有所有逻辑的方法 但我有问题 我需要在哪里导入它 在类中或外部
  • Excel 数据透视表 - 计算总和的平均值

    我确信这很简单 但是如何获得数据透视表来显示计算出的字段总和的平均值 在简化的示例中 我过滤掉了资金 x1 数据透视表显示了每人剩余资金的总和 现在我如何获得平均值按人 所以 手动计算 3300 3 我尝试使用计算字段 但无法弄清楚它是如何
  • Python xpath 不工作?

    好吧 这开始让我有点抓狂了 我已经尝试了几个 Python 的 xml xpath 库 但无法找到一种简单的方法来获取臭味十足的 标题 元素 最新的尝试如下所示 使用 Amara def view req url req content t
  • 该方法必须返回 boolean(Java) 类型的结果

    这是我的代码 boolean checkHit2 if cx lt 0 cx gt 640 return true if cy lt ground int cx return false if cx lt blue 15 cx gt blu
  • 如何在 C 中的 3d 数组中使用 memcpy

    我有一个 3 维数组int32 t x 1024 4 256 我需要将数组的所有元素复制到相同类型和大小的另一个数组int32 t y 1024 4 256 我可以用吗memcpy y x sizeof x 之后我可以访问数组的元素y与x
  • 将文件保存到 MyDocuments + 应用程序文件夹

    我正在尝试将 NET 应用程序设置文件保存到用户的 MyDocument MyApplication 文件夹 但我不知道如何检查现有文件夹 文件 并在保存时创建或附加文件夹 文件 我不想打开 saveFileDialog 因为我需要该文件位
  • SSE 错误 - 使用 m128i_i32 定义 __m128i 变量的字段

    定义一个 m128i变量以这种方式 m128i a a m128i i32 0 65000 我收到以下错误 错误 请求 a 中的非类成员 m128i i32 类型 m128i 又名 vector 2 long long int a m128
  • XPath 查找具有特定子节点的所有元素

    您能帮我找到下面示例中具有子元素 c 的所有元素 b 吗 a b b b b a
  • spring 拦截器从未被调用

    我有以下拦截器 Component public class ExternalLinkInterceptor extends HandlerInterceptorAdapter private static final Logger log
  • 使用 sse 指令进行复杂的 Mul 和 Div

    通过 SSE 指令执行复杂的乘法和除法是否有益 我知道使用 SSE 时加法和减法表现更好 有人可以告诉我如何使用 SSE 执行复杂的乘法以获得更好的性能吗 为了完整起见 可以下载 英特尔 64 和 IA 32 架构优化参考手册 here h
  • 我是否必须取消订阅ActivatedRoute(例如参数)可观察量?

    我发现很多例子ActivatedRoute可观察到的像params or url已订阅但未取消订阅 constructor private route ActivatedRoute ngOnInit this route params co
  • Amazon S3 - 如何下载匿名用户拥有的对象?

    我有一个示例网页 允许匿名用户上传对象并在我的 S3 存储桶中创建文件夹 不幸的是 在执行此操作之前 我没有设置任何特定的存储桶策略或 ACL 现在我遇到一个问题 匿名用户创建了一个文件夹并上传了我 作为根用户 无法下载或访问的对象 我计划
  • 基于referer的nginx条件路由

    我需要根据 http 请求来源路由流量 我有两个环境 我们需要使用 http referer 将 us en 的每个 http 请求重定向到环境 1 将其他请求重定向到环境 2 基于位置的重定向有效 location us en proxy