我看到这个问题要求1001次以上,并且坦率地说,无法通过nginx和PHP设置来实现这一点。我必须在生产中修复遗留应用程序,nginx和php-fpm在同一个盒子上运行 - 这意味着他们共享这个目录。
我的情况不同于99.999%的设置,因为我只允许提供类似STATIC的网站;但是,允许加载2或3个小PHP脚本页面。 除非已经匹配了显式URI,否则我不想允许执行PHP运行时。
不幸的是,如果有人要猜测'它是服务器上的一个php文件,下载了!
我认为这是一个解决方案。但我需要有比我更多nginx经验的人来验证这个,因为它是一个敏感的网站。我只是无视任何PHP来做到这一点:
#
# case-insensitive match of anything *.php
location ~* \.php {
# never allow a single .php page to run, ever.
# no parsing, no lookup, nada. stop dead in tracks.
return 404;
}
没有此块,nginx会将下面的/var/www/cat-videos/cats.php文件作为下载文件发送!
我发现nginx会下载文件,因为( drumroll - 因为没有人能够解释为什么会发生这种情况 - 鼓声):
default_type
设置为application/octet-stream
(也称为下载)。将此更改为,例如,text/plain
显示PHP而不是下载它。这证明了这个配置变量是它的一部分。root
目录中的所有文件,无论其类型如何。如果没有匹配的mime-type,它将使用上面的default_type
。你有它。如果您不想要它,请不要将文件放在nginx可以看到的地方! (相反,将所有php文件移动到root
指令之外的另一个目录,并配置fastcgi以在其他地方进行通话)。例如。 /var/www/mysite-scripts-only/
代替/var/www/mysite-static-version/
。
php和静态网站有哪些最佳做法可以防止这种情况发生?将脚本移动到其他目录?运行两个不同的服务器,并使用proxy_pass
?
我认为最好将所有脚本文件(python,php,ruby等 - 所有类型的脚本)从静态文件中完全分开。并为类型设置特定的location
指令,您可以通过proxy_pass
或fastcgi
或passenger
或类似的方式控制脚本访问。
这允许nginx默认提供静态站点中的任何内容,非常静态。
不,我不是在谈论"只需将X添加到location
,而fastcgi应该阻止下载 - 不。我需要完全保证这永远不会再发生。从静态文件中分离脚本文件似乎是唯一100%这样做的方法,因为nginx只想在其根目录中提供所有内容。
可能会有更多特定的location
覆盖或网址重写,这也会阻止所有请求在nginx中传递。还有可能在 root
中使用其他location
指令 - 但从我读到的内容来看,这通常是不受欢迎的。但是,解决这个问题超出了范围和时间。
对于记录,这是我以前的nginx配置阻止php下载:
/etc/nginx/conf.d/default.conf
。以下是/etc/nginx/nginx.conf
的相关内容。 (不使用conf.d/*
,并不重要。)
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
include /etc/nginx/mime.types;
default_type application/octet-stream;
gzip on;
...
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=reverse_cache:60m inactive=90m max_size=1000m;
...
server {
...
# Domain
server_name somerandomurl.blah;
root /var/www/cat-videos;
############################################
# STATIC FILES SECTION
############################################
location / {
index index.html
try_files index.html =404;
}
location /assets/css/ {
}
location ~* .(jpg|png|gif|jpeg|css|txt)$ {
proxy_cache_valid 200 120m;
proxy_cache_lock on;
expires 1d;
access_log off;
}
############################################
# DYNAMIC PHP AREA ** DANGER ZONE **
############################################
#
# case-insensitive match of anything *.php
location ~* \.php {
# never allow a single .php page to run, ever.
# no parsing, no lookup, nada. stop dead in tracks.
return 404;
}
# expose only 1 PHP page.
# NOTE the SCRIPT_FILENAME I am setting manually. This works fine.
# for normal php sites, you'd most likely want to setup clean urls
# and not use the php suffix, and use some of the normal vars you
# see in the 1001+ tutorials out there.
location ~ /process/cat-videos {
include fastcgi_params;
#fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_pass php:9000;
fastcgi_param SCRIPT_FILENAME /var/www/cat-videos/cats.php;
}
那是旧的配置。我已经从静态目录中分离出所有脚本,并将fastcgi配置为与其他目录通信,如:
fastcgi_param SCRIPT_FILENAME /var/www/mysite-scripts-only/cats.php;
那些想让它保持动态的人可能想把它改成:
# don't use $document_root prefix on the path, move scripts elsewhere
fastcgi_param SCRIPT_FILENAME /var/www/mysite-scripts-only$fastcgi_script_name;
谢谢!
答案 0 :(得分:0)
我已经与nginx和这个设置上的更多用户进行了交谈,并且除了我在原始问题中描述的内容之外,似乎没有任何其他方式。
他们说通过使用不同的根目录从静态文件中拆分脚本真的是最好的方法,我已经做到了。
因此,标记我自己的问题,因为它现在应该是一个Wiki。