【问题标题】:php-fpm - How to execute certain symlinks as PHP scriptsphp-fpm - 如何将某些符号链接作为 PHP 脚本执行
【发布时间】:2014-11-04 19:46:58
【问题描述】:

我正在运行带有 FastCGI 和 php-fpm 的 Apache 2.2。我正在尝试复制以下逻辑:

<FilesMatch "^(admin|api|app)?(_dev)?$">
    #ForceType application/x-httpd-php
    SetHandler php-fcgi
</FilesMatch>

这允许我将 admin.php 符号链接为管理员,因此我可以删除 .php 扩展名。似乎使用 php-fpm 执行此操作的唯一方法是将 www.conf 文件的 security.limit_extension 设置为空,但是,正如 cmets 所指出的,这是一个相当大的安全漏洞,因为现在 php 代码可以从任何文件中执行,无论扩展名如何。

什么是完成上述任务的首选方法,但仍保持一些安全性?

【问题讨论】:

    标签: apache fastcgi php


    【解决方案1】:

    @Mike,根据您更新的答案,类似于此 .htaccess 文件的内容应该能够处理您要执行的操作:

    # Enable the rewrite engine
    RewriteEngine on
    # Set the rewrite base path (i.e. if this .htaccess will be running at root context "/" or a subdir "/path")
    RewriteBase /
    
    # If the file exists, process as usual.
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule .* - [NC,L]
    
    # If the dir exists, process as usual (if you don't need this, just comment/remove the next two lines).
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule .* - [NC,L]
    
    # If (requested_file_name).html exists, rewrite to that file instead.
    RewriteCond %{REQUEST_FILENAME}\.html -f
    RewriteRule ^(.*)$ $1.html [QSA,L]
    
    # If (requested file name).php exists, rewrite to that file instead.
    RewriteCond %{REQUEST_FILENAME}\.php -f
    RewriteRule ^(.*)$ $1.html [QSA,L]
    
    # If none of the above rules were triggered, fallback to index.php.
    RewriteRule ^(.*)$ index.php [QSA,L]
    

    通过一些调整,这应该能够完成这项工作,而无需深入研究 httpd.conf&lt;VirtualHost&gt;&lt;FilesMatch&gt; 指令。希望这会有所帮助。

    【讨论】:

    • 谢谢老兄,我会试一试。我尝试实施重写规则但没有成功,因为我尝试的规则与您提出的不同,所以也许您的规则可行。
    • 是的,我明白你的意思......我自己已经花费了无数个小时来调试和弄清楚为什么重写规则不能正常工作......
    • 继续选择您的答案,因为我相信这会奏效,只是现在没有时间尝试。
    【解决方案2】:

    目前看来最好的解决方案是将已知的符号链接手动添加到列表中(位于 /etc/php-fpm.d/www.conf):

    security.limit_extension php admin admin_dev api api_dev app app_dev
    

    不确定 security.limit_extension 指令是否甚至可以采用正则表达式,看起来不像,所以这和它得到的一样好。如 OP 中所述,您仍然需要在 vhost 配置中维护 filesmatch 指令:

    <FilesMatch "^(admin|api|app)?(_dev)?$">
        SetHandler php-fcgi
    </FilesMatch>
    

    -- 更新--

    根据 tftd 的 cmets,添加当前的重写指令:

    RewriteBase /
    
    # we skip all files with .something
    RewriteCond %{REQUEST_URI} \..+$
    RewriteCond %{REQUEST_URI} !\.html$
    RewriteRule .* - [L]
    
    # we check if the .html version is here (caching)
    RewriteRule ^$ index.html [QSA]
    RewriteRule ^([^.]+)$ $1.html [QSA]
    RewriteCond %{REQUEST_FILENAME} !-f
    
    # no, so we redirect to our front web controller
    RewriteRule ^(.*)$ index.php [QSA,L]
    

    【讨论】:

    • 只是出于好奇——为什么不直接使用mod_rewrite 而不是FilesMatch
    • @tftd:我愿意接受建议,我不确定如何编写 mod_rewrite 以便它像 php 代码一样提供符号链接?
    • 好吧,据我了解,您可能正在尝试执行 MVC/SEO 链接 - 即 /admin/something 会在后台默默地将请求重定向到 /admin.php?page=something,就好像那是原始请求一样.如果是这种情况,您可能会发现此链接很有用:garajau.com.br/blog/2013/12/…
    • @tftd:感谢您提供的信息,但我仍在使用 httpd v2.2。我也不想转换 /admin.php?page=something,我只是想删除 .php 扩展名,这样 /admin.php 和 /admin 都可以工作。它基于具有某些重写规则的 SF 框架,而 FilesMatch 指令是使其工作的唯一方法。
    • 我明白了,在这种情况下,您可以使用类似于此重写的方法来做到这一点:RewriteCond %{REQUEST_FILENAME} !-f(新行)RewriteRule ^(.*)$ $1.php [L]。这将重写所有不存在文件的请求,以.php 结尾。示例:/test 将被重写为 /test.php。如果要重写特定文件,请将 RewriteRule 更改为:RewriteRule ^(admin|api|app)$ $1.php
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-09
    • 2019-03-21
    • 1970-01-01
    • 2012-05-27
    • 2019-10-08
    • 1970-01-01
    相关资源
    最近更新 更多