在nginx中编码和解码路径名

时间:2017-12-22 05:11:33

标签: nginx encryption configuration

通常可以通过以下方式访问文件:

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

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

http://example.com/Y2F0cy9jYXQxLnppcAo=

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

4 个答案:

答案 0 :(得分:3)

如果您唯一关注的是限制对某些网址的访问权限,则可以使用this post on Securing URLs查看Secure Link Module in Nginx

它提供了相当简单的文件保护方法 - 加密网址的最基本和最简单的方法是使用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;
    }
}

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

  1. 哈希后面的网址部分,在我们的案例中为cat1.zip
  2. secure_link_secret指令的参数,本例中为yoursecretkey
  3. 上述示例还假设通过加密URL可访问的文件存储在/path/to/secret/files/secure目录中。

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

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

    1. 在Nginx端处理加密URL的解密 - 编写自己的,或重用其他人编写的模块
    2. 在应用程序的某处处理加密URL的解密 - 基本上使用Nginx将加密的URL代理到您解密它们的应用程序并采取相应的行动,如@cnst所述。
    3. 这两种方法都有利有弊,但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;
          }
      }
      

      并且在应用程序(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可访问(正确加密),您发送文件以供下载,但如果您需要执行其他操作,则会应用相同的逻辑。

答案 1 :(得分:2)

您可以使用Nginx rewrite rule重写网址(从编码到未编码)。而且,要应用编码逻辑,您可以使用自定义函数(我使用perl module完成)。

可能是这样的:

-feeds container
--- facebook container
------facebook icon
------facebook feed
--- twitter container
------twitter icon
------facebook feed
--- instagram container
------instagram icon
------instagram feed

答案 2 :(得分:1)

最简单的方法是编写一个简单的后端(例如,通过proxy_pass连接),它将解密$uri中的文件名,并在X-Accel-Redirect内提供结果响应标头(在nginx中受proxy_ignore_headers影响),随后将受到nginx内的internal重定向(到不首先通过后端无法访问的位置),并且服务于所有已经成为nginx一部分的优化。

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

上述方法遵循'微服务'架构,因为解密器服务的唯一工作是执行解密和访问控制,将其留给nginx以确保文件正确并以最有效的方式通过使用内部经过特殊处理的X-Accel-Redirect HTTP响应标头。

答案 3 :(得分:1)

考虑使用Lua等OpenResty。

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

https://openresty.org/

https://github.com/openresty/