在nginx中编码和解码路径名

use*_*697 8 encryption configuration nginx

通常可以在以下位置访问文件:

http://example.com/cats/cat1.zip

我想编码/加密路径名(/cats/cat1.zip),以便链接通常不可访问,但在路径名加密/编码后可访问:

http://example.com/Y2F0cy9jYXQxLnppcAo=

我上面使用base64编码是为了简单,但更喜欢加密.我该怎么做呢?我是否必须编写自定义模块?

van*_*00j 6

如果您唯一关心的是限制对某些 URL 的访问,您可以查看这篇关于使用Nginx 中安全链接模块保护 URL 的帖子

它提供了相当简单的方法来保护你的文件——加密你的 URL 的最基本和最简单的方法是使用secure_link_secret指令:

server {

    listen 80;
    server_name example.com;

    location /cats {
        secure_link_secret yoursecretkey;
        if ($secure_link = "") { return 403; }


        rewrite ^ /secure/$secure_link;
    }


    location /secure {
        internal;
        root /path/to/secret/files;
    }
}
Run Code Online (Sandbox Code Playgroud)

访问cat1.zip文件的 URL将是http://example.com/cats/80e2dfecb5f54513ad4e2e6217d36fd4/cat1.zip80e2dfecb5f54513ad4e2e6217d36fd4连接两个元素的文本字符串上计算的 MD5 哈希值的位置:

  1. 在我们的例子中,跟在哈希后面的 URL 部分 cat1.zip
  2. secure_link_secret指令的参数,在这种情况下yoursecretkey

上面的例子还假设通过加密 URL 访问的文件存储在/path/to/secret/files/secure目录中。

此外,还有一种更灵活但也更复杂的方法,ngx_http_secure_link_module通过使用secure_linksecure_link_md5指令使用模块保护 URL,通过 IP 地址限制 URL 访问,定义 URL 的到期时间等。

如果您需要完全隐藏您的 URL(包括cat1.zip部分),您需要在以下各项之间做出决定:

  1. 在 Nginx 端处理加密 URL 的解密——自己写,或者复用别人写的模块
  2. 在你的应用程序中处理加密 URL 的解密——基本上是使用 Nginx 将你的加密 URL 代理到你的应用程序,在那里你解密它们并采取相应的行动,如上面@cnst所写。

这两种方法各有利弊,但 IMO 后一种更简单、更灵活——一旦你设置了你的代理,你就不需要太担心 Nginx,也不需要用一些特殊的先决条件来编译它;无需使用您已在应用程序中编写的语言以外的语言编写或编译代码(除非您的应用程序包含 C、Lua 或 Perl 代码)。

这是一个简单的 Nginx/Express 应用程序示例,您将在其中处理应用程序中的解密。Nginx 配置可能如下所示:

server {

    listen 80;
    server_name example.com;

    location /cats {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-NginX-Proxy true;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_pass http://127.0.0.1:8000;
    }

    location /path/to/secured/files {
        internal;
    }
}
Run Code Online (Sandbox Code Playgroud)

在应用程序(Node.js/Express)方面,您可能有以下内容:

const express = require ('express');
const app = express();

app.get('/cats/:encrypted', function(req, res) {
  const encrypted = req.params.encrypted;

  // 
  // Your decryption logic here
  //
  const decryptedFileName = decryptionFunction(encrypted);

  if (decryptedFileName) {
    res.set('X-Accel-Redirect', `/path/to/secured/files/${decryptedFileName}`);
  } else {
    // return error
  }
});


app.listen(8000);
Run Code Online (Sandbox Code Playgroud)

上面的例子假设受保护的文件位于/path/to/secured/files目录中。它还假设如果 URL 可访问(正确加密),您正在发送文件以供下载,但如果您需要做其他事情,则相同的逻辑将适用。


sha*_*awn 5

考虑将 OpenResty 之类的东西与 Lua 结合使用。

Lua 几乎可以在 nginx 中完成你想做的所有事情。

https://openresty.org/

https://github.com/openresty/

====更新====

现在我们有了njs https://nginx.org/en/docs/njs/,nginx 的 javascript,它几乎可以做所有事情。


Gon*_*heu 5

您可以使用Nginx 重写规则重写 url(从编码到未编码)。而且,要应用您的编码逻辑,您可以使用自定义函数(我使用perl 模块做到了)。

可能是这样的:

 http {
  ...
    perl_modules perl/lib;
    ...
    perl_set $uri_decode 'sub {
      my $r = shift;
      my $uri = $r->uri;
      $uri = perl_magic_to_decode_the_url;
      return $uri;
    }';
    ...
    server {
    ...
      location /your-protected-urls-regex {
        rewrite ^(.*)$ $scheme://$host$uri_decode;
      }
Run Code Online (Sandbox Code Playgroud)


cns*_*nst 4

最简单的方法是编写一个简单的后端(proxy_pass例如,通过 进行接口),该后端将从 中解密文件名$uri,并在响应标头中提供结果X-Accel-Redirect(在 nginx 中受此限制proxy_ignore_headers),该响应标头随后将受internal在 nginx 内重定向(到一个不先通过后端就无法访问的位置),并提供 nginx 已经一部分的所有优化。

\n\n
location /sec/ {\n    proxy_pass http://decryptor/;\n}\nlocation /x-accel-redirect-here/ {\n    internal;\n    alias \xe2\x80\xa6;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

上述方法遵循 \xe2\x80\x98microservices\xe2\x80\x99 架构,因为解密器服务的唯一工作是执行解密和访问控制,将其留给 nginx 来确保正确提供文件并在最有效的方法是使用内部经过特殊处理的X-Accel-RedirectHTTP 响应标头。

\n