jnb*_*bdz 1 security nginx php5
我正在尝试使用 NGiNX 和 PHP 保护我的服务器上的文件(多种类型)。
基本上,我希望人们如果想访问图像等静态文件,就必须登录网站。DropBox 做得很好。他们在哪里强迫您登录以访问您放在那里的服务器上的任何静态文件。
我想使用NGiNX Perl 模块。我会编写一个 perl 脚本来检查会话以查看用户是否已登录以授予他们对静态文件的访问权限。
我更喜欢使用 PHP,因为我所有的代码都在 PHP 下运行,我不确定如何使用 PERL 检查由 PHP 创建的会话。
所以基本上我的问题是:如何保护需要用户登录并使用 PHP 脚本创建有效会话的任何类型的静态文件?
cyb*_*x86 11
你要问的有两件事:
希望这能澄清每个组件所扮演的角色——尽管它可能有点过分。
防止外部访问文件:
这部分由您的 Web 服务器完成 - 在本例中为 nginx。
在您的 nginx 配置(您的服务器块)中,您指定一个root路径。默认情况下,此根路径下的所有文件都可以直接访问。
例如,请考虑以下内容(域为“example.com”)
root /var/www/example.com/public_html
Run Code Online (Sandbox Code Playgroud)
如果您有一个文件 ,uploaded_file.zip则可以通过以下方式访问它:
本质上,文档根目录上方的文件将无法通过浏览器访问,但是,PHP 的大多数配置将允许您的代码读取文件并传送它(对此的限制通常是由于open_basedir)
在某些情况下,最好将文件放在文档根目录下。要做到这一点并仍然阻止(直接)外部访问,您将使用该internal指令。例如:
位置/上传{内部;}
现在,放置在 /var/www/example.com/public_html/uploads 中的任何文件只能在内部访问(即不能通过浏览器访问,但可以通过您的 PHP 脚本访问)。如果需要,您还可以在 /uploads 位置设置别名,以便也可以使用另一个路径来引用它。
此时,您的文件无法直接访问,但您的脚本仍然可以为它们提供服务。
用户身份验证和 PHP:
考虑以下基本设计:用户可以直接访问文件,也可以进入登录页面。如果他们尝试直接访问文件并已登录(并具有权限),则该文件将被下载,否则,他们将最终出现在登录屏幕上。要上传文件,用户需要登录。
假设您的下载脚本(将文件传送给用户的页面)称为“download.php”。典型的 URL 可能是 example.com/download.php?file=uploaded_file.zip。您很可能不希望您的 URL 包含 php 文件名。为避免这种情况,您可以在 nginx 配置中设置重写规则,该规则将指向脚本中的另一个位置(比如 /files)。添加到您的 nginx 配置:
rewrite ^/files/(.*) /download.php?file=$1 last;
Run Code Online (Sandbox Code Playgroud)
(这相当于更改以 /files 开头的任何请求的请求路径,并捕获 / 之后的所有内容并将其作为查询参数传递给您的 php 文件);
现在,您的文件可以通过以下方式访问:example.com/files/uploaded_file.zip(内部重定向到您的 php 脚本)。
您的 PHP 文件 (download.php) 现在执行以下操作:
输出必要的标题(Content-Type、Content-Disposition 等)并设置:
X-Accel-Redirect: /uploads/uploaded_file.zip;
请注意,您可以完全从 PHP 进行实际下载(例如使用readfile)- 通过 nginx 进行下载效率更高,尤其是对于大文件)。此外,尽管用户似乎直接访问该文件,但在内部,它正在通过 PHP,在允许他们继续之前对其进行身份验证。
URL -> nginx (redirect to PHP) -> PHP (authenticate) -> nginx (serve file)
Run Code Online (Sandbox Code Playgroud)
在上传方面,您将move_uploaded_file/var/www/example.com/public_html/uploads(受“内部”指令保护,因此无法直接访问文件),并将权限保存到您的数据库。