在nginx中编码和解码路径名

在nginx中编码和解码路径名,nginx,encryption,configuration,Nginx,Encryption,Configuration,通常情况下,可以在以下位置访问文件: 我想对路径名(/cats/cat1.zip)进行编码/加密,以便在对路径名进行加密/编码后,链接通常不可访问: 为了简单起见,我使用上面的base64编码,但更喜欢加密。我该怎么做呢?我必须编写自定义模块吗?最简单的方法是编写一个简单的后端(例如通过接口),从$uri解密文件名,并在X-Accel-Redirect响应头中提供结果(在nginx中受限制),随后将在nginx内进行重定向(到不首先通过后端就无法访问的位置),并提供nginx已经包含的所有优

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

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


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

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

location /sec/ {
    proxy_pass http://decryptor/;
}
location /x-accel-redirect-here/ {
    internal;
    alias …;
}

上述方法遵循“微服务”体系结构,因为解密器服务的唯一任务是执行解密和访问控制,由nginx负责,通过使用内部经过特殊处理的
X-Accel-Redirect
HTTP响应头,确保以最有效的方式正确提供文件。

考虑使用类似OpenResty的Lua

Lua在nginx中几乎可以做任何你想做的事情

==更新====

现在我们有了njs,nginx的javascript,它几乎可以做任何事情。

您可以使用重写url(从编码到未编码)。并且,为了应用编码逻辑,您可以使用自定义函数(我使用了)

可能是这样的:

 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;
      }

如果您唯一关心的是限制对某些URL的访问,您可以使用查看

它提供了相当简单的保护文件的方法-加密URL的最基本、最简单的方法是使用
secure\u link\u 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;
    }
}
访问
cat1.zip文件的URL将是
http://example.com/cats/80e2dfecb5f54513ad4e2e6217d36fd4/cat1.zip
其中
80e2dfecb5f54513ad4e2e6217d36fd4
是在连接两个元素的文本字符串上计算的MD5哈希:

  • 在本例中,URL中哈希后面的部分是
    cat1.zip
  • secure\u link\u secret指令的参数,在本例中为
    yoursecretkey
  • 上述示例还假设通过加密URL访问的文件存储在
    /path/to/secret/files/secure
    目录下

    此外,还有一种更灵活、但也更复杂的方法,通过使用
    secure\u link
    secure\u link\u md5
    指令,使用
    ngx\u http\u secure\u link\u module
    模块保护URL,以限制IP地址对URL的访问,定义URL的过期时间等

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

  • 在Nginx端处理加密URL的解密-编写自己的,或重用其他人编写的模块
  • 处理应用程序中某个加密URL的解密-基本上使用Nginx将加密URL代理到应用程序,在应用程序中解密URL并相应地执行操作,如上所述
  • 这两种方法各有利弊,但在我看来,后一种方法更简单、更灵活——一旦您设置了代理,您就不需要担心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;
        }
    }
    
    在应用程序(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);
    

    上述示例假定受保护的文件位于
    /path/to/secured/files
    目录。此外,它还假设如果URL是可访问的(正确加密),则您正在发送文件以供下载,但如果您需要执行其他操作,则同样的逻辑也适用。

    看来echo-n'cat1.zipyoursecretkey'| openssl md5-hex不会生成您提供的哈希。你能解释一下原因吗?