安全链接仅取决于目录名称?

我目前正在努力使nginx安全的文件夹名称,无论其内部的文件名是什么。 比方说,我正在访问一个文件夹/一个/两个/三个文件,它看起来像这样:

所以文件夹“三”只能通过目录md5访问,而真正的path将返回403.我有成千上万的这样的文件夹,所以我需要保持隐藏,但通过远程客户端,只知道md5静态访问他们运行。

同时这样的链接也应该工作:

所以只有一个特定的目录级别被隐藏。

您可以通过使用隐藏文件夹或文件的内部位置来达到此目的,以及检查散列代码是否允许访问您的文件的方法。

Nginx不允许直接访问您的隐藏文件(例如/protected/folder1/folder2/file.pdf),因为该位置已被标记为内部文件。 但是您的脚本可以使用特殊标题X-Accel-Redirectredirect到此位置。

所以你可以让Nginx做它最擅长的事情,只有在允许或不允许访问的情况下才能提供数据和脚本检查。

下面你可以看到一个简单的例子。

该文件夹/数据包含公共内容(例如公共图像)。 没有公共图像存储在不同的文件夹(htdocs之外),并通过位置/保护数据提供。 该位置具有包含受保护图像的文件夹和指令内部的别名。 所以这是不能从外面访问的。

在PHP脚本中,我首先检查受保护的文件是否存在。 这可能是一个安全问题,但通常检查用户权限比简单的file_exists更昂贵(耗时)。 因此,如果安全性比性能更重要,则可以切换检查顺序。

Nginx服务器configuration:

... root /var/www/test/htdocs; location / { index index.php index.htm index.html; } location /data { expires 30d; try_files $uri /grant-access.php; } location /protected_data { expires off; internal; alias /var/www/test/protected_data; } location ~ \.php$ { if (!-e $request_filename) { rewrite / /index.php last; } expires off; include fastcgi_params; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_read_timeout 300; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; access_log /var/log/nginx/access.log combined; } ... 

PHP脚本:

 <?php // this is the folder where protected files are stored (see Nginx config alias directive of the internal location) define('PROTECTED_FOLDER_FILESYSTEM', '/var/www/test/protected_data'); // this is the url path we have to replace (see Nginx config with the try_files directive) define('PROTECTED_PUBLIC_URL', '/data'); // this is the url path replacement (see Nginx config with the internal directive) define('PROTECTED_INTERNAL_URL', '/protected_data'); // check if file exists $filename = str_replace( PROTECTED_PUBLIC_URL .'/', '/', parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) ); if (!file_exists(PROTECTED_FOLDER_FILESYSTEM . $filename)) { http_response_code(404); exit; } // check if access is allowed (here we will use a random check) if (rand(1,2)==1) { // grant access header('X-Accel-Redirect: ' . PROTECTED_INTERNAL_URL . $filename); } else { // deny access http_response_code(403); } 

为了使这成为可能,nginx将需要能够告诉散列35d6d33467aae9a2e3dccb4b6b027878对应于three 。 Nginx无法做到这一点今天(我不认为它是在待办事项列表)。

我可以想象如何才能实现类似的东西的唯一方法是将文件托pipe在另一个位置,并创build符号链接与目标目录的散列作为链接​​名称在您的位置的根目录中创build文件的时间点/上传。

例如,您的Web服务器位置http://example.com/one/two/指向一个目录(比如说/var/www/html/ ),其中符号链接35d6d33467aae9a2e3dccb4b6b027878指向位于另一个位置(例如, /var/www/protected/ )。

上传将需要触发一个脚本或类似的东西,以创build文件夹three/ in /var/www/protected/ ,散列“三”,然后创build符号链接/var/www/html/35d6d33467aae9a2e3dccb4b6b027878

这是我能想到的唯一方法。