我在 Ubuntu 12 上运行 LAMP 堆栈,其主要功能是提供基于 PHP 的 API。
我只想向公众公开一个文件,名为:api.php
它需要引用我拥有的包含数据库密码的配置文件,/cfg/api-config.php
以便 API 可以写入数据库等。
所以我只希望api.php
由 apache 提供并公开。
我放入 /cfg 的配置文件必须可被 api.php 读取,但不能被访问该站点的任何人读取。
我没有.htaccess
,只是httpd.conf
按照下面的内容进行了配置。
<VirtualHost *:44448>
DocumentRoot "/api"
ServerName localhost:44448
ServerAlias Server.local
DirectoryIndex index.html
CustomLog "/var/log/apache_access.log" combined
ErrorLog "/var/log/apache_error.log"
SetEnv APPLICATION_ENV development
php_flag magic_quotes_gpc off
<Directory "/api">
Options Indexes MultiViews FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
/cfg
我的和文件夹的权限/api
为:以及位于drwxr-xr-x
的带有数据库密码的敏感配置文件的权限/cfg/api-config.php
-rw-r--r--
我想知道是否有人可以告诉我这个设置是否正确且安全?
其中:
A) 除此之外的所有文件都不/api/api.php
公开,并且无法访问我的服务器文件。
B) 访问该网站的任何人都无法读取包含数据库密码(用于 API)的配置文件?
我尝试通过在 中创建一个新文件夹来测试这一点/cfg
,chmod 777
但似乎无法访问它,这很好!
答案1
您有两个文件(假设它们位于 /var/www)
- /var/www/api/api.php
- /var/www/cfg/api-config.php
首先,使用 apache 限制对 /cfg 的访问(确保没有人可以从 http 访问它)并允许访问 /api:
<Directory /var/www/api>
Options None
AllowOverride None
Order allow,deny
Allow from all
<Directory>
<Directory /var/www/cfg>
Options None
AllowOverride None
Order allow,deny
Deny from all
<Directory>
接下来,使用 open_basedir 限制你的 php:
open_basedir = /var/www/api:/var/www/cfg
(如果需要,请在此处添加 /tmp、session 和其他目录)
接下来,更改 /var/www/cfg 目录和 /var/www/cfg/api-config.php 文件的访问模式(假设您的 apache 用户是 www-data):
chown -Rv root:root /var/www/{cfg,api}
chmod -v 711 /var/www/cfg
chmod -v 755 /var/www/api
chmod -v 644 /var/www/api/api.php /var/www/cfg/api-config.php
通过使用711在 /cfg 上,您可以确保没有人可以读取(列出)目录的内容,但仍然可以读取 api-config.php(您需要它来通过 PHP 读取文件)
答案2
首先,我将更改您的 cfg 及其中的文件的文件权限。如果您在其中存储 DB 设置,则这是读取访问权限,应删除写入访问权限。最好将您的 Apache HTTP 守护进程环境设置为安全,但这是另一层安全性。您的 PHP 安装在 HTTP 守护进程的用户上下文中运行,因此我个人甚至会删除该组的读取访问权限。我很好奇您进行的测试。cfg 文件夹似乎不在您的 DocumentRoot 下,因此乍一看似乎无法通过 HTTP 服务器访问。但试图闯入您的安装的人不会依赖这种方法。您的配置中有 AllowOverride All Order allow,deny Allow from all,这仅仅意味着:根本没有访问控制。您还声明了 FollowSymLinks,这会带来其他安全影响。因此,此安装远远落后于安全性。您可以通过将 .htaccess 文件放入安装的 DocumentRoot 中来保护您的 cfg 文件夹。其中的条目可以强力保护文件和目录访问,例如
<Files RELEASE_NOTES.txt>
order allow,deny
denied from all
</Files>(取自 magento 安装)
如果您想知道 FollowSymLinks 的安全影响:请记住,PHP 在您的 Apache HTTP Daemon 安装上下文中运行,并且 PHP 可以在您的文件系统上执行写入操作。如果 PHP 代码插入到您的应用程序中,在其上创建符号链接,那么某人只需创建指向他或她感兴趣的系统部分的符号链接,就可以监视您的文件系统。将一个简单的 .htaccess 文件放入您的 cfg 目录中,格式为 Order allow,deny Deny from all,这将删除通过 HTTP Daemon 浏览此目录的能力。如果您的 api.php 是 PHP 安装/Webapp 的前端控制器,您应该考虑使用 Apache 的 mod_rewrite 重写所有请求的 URL 以指向您的 api.php,例如
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^ api.php [L]
在 .htaccess 文件中,您将其放入 /api 目录,它将把所有请求路由到您的 api.php。例如 localhost:44448/someURL?id=988 将在内部变为请求 localhost:44448/api.php?id=988。
澄清一下:
重写规则不应用于访问控制,它们主要用于更改请求的处理方式。
许多 PHP 框架或 CMS 使用 RewriteRules 为 Web 应用程序提供一个中央入口点,应用程序组件在此加载,路由组件可能被调用,并且 URL 参数到内部结构的转换也执行。
例如,Symfony2 将查询/和 Post 参数转换为更面向对象的结构,并将其封装到对象中。Symfony2
还利用安全概念,在生成 HTTP 响应之前读取路由信息和配置,例如确保已执行身份验证或用户必须具有访问 URL 路径的正确用户角色。
答案3
您似乎做了一件至关重要的事情,那就是将其放在/cfg/api-config.php
DocumentRoot 之外。如果/cfg
不在 URL 空间内,则网站用户无法读取它。这是您可以采取的最基本的预防措施。
用户是否仍有可能读取该文件?当然,如果您在其他地方破坏了配置(例如,通过对文件设置Alias
或RewriteRule
),或者应用程序做了一些愚蠢的事情(例如输出文件的内容)。应用程序漏洞才是真正的问题:应用程序必须能够读取文件,应用程序越复杂,就越有可能存在隐藏的漏洞。但就 Apache 配置而言,我认为您已经完成了。
答案4
除了上述建议之外,我建议删除 apache 用户拥有的 DocumentRoot 中所有文件/文件夹的写入权限。(例如 api.php 文件)这假设 api.php(或它调用的任何内容)不需要向本地 Web 服务器写入任何内容。这应该有助于防止将不需要的文件写入 Web 服务器