活到老学到老  

记录遇到问题的点点滴滴。

nginx php-fpm 防止跨目录访问

7年前发布  · 2017 次阅读
  nginx  php-fpm 

使用场景:

一台服务器有多个项目,不同的项目有不同的开发人员或者外部开发人员,在代码量大或者项目赶的时候根本没时间审查代码,为了避免跨目录访问造成比不必要的损失,我们要限制每个项目只能访问本项目的目录,并且不允许执行敏感函数,而且可以避免一个站点漏洞导致一个服务器的所有站点遭殃。

声明下此种方法配置后非常不稳定(或许我版本原因php5.6+nginx1.10.1),时而有效时而无效,推荐使用防跨目录功能使用.user.ini此方法有效也稳定。

Nginx配置

可以利用php的open_basedir方式跨目录访问,但是还不够使用php的exec system等命令还可以访问,所有敏感函数也要禁用。

nginx为例

编辑/etc/nginx/fastcgi_params每个项目只允许访问本目录并且禁用不安全函数

追加

fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root:/tmp/
disable_functions=pcntl_alarm, pcntl_fork, pcntl_waitpid, pcntl_wait, pcntl_wifexited, pcntl_wifstopped, pcntl_wifsignaled, pcntl_wexitstatus, pcntl_wtermsig, pcntl_wstopsig, pcntl_signal, pcntl_signal_dispatch, pcntl_get_last_error, pcntl_strerror, pcntl_sigprocmask, pcntl_sigwaitinfo, pcntl_sigtimedwait, pcntl_exec, pcntl_getpriority, pcntl_setpriority, eval, popen, passthru, exec, system, shell_exec, proc_open, proc_get_status, chroot, chgrp, chown, ini_alter, ini_restore, dl, pfsockopen, openlog, syslog, readlink, symlink, popepassthru, stream_socket_server, fsocket, chdir";

重新加载nginx配置即可

nginx -s reload

写个php测试下

<?php
system('ls');
file_put_contents('../b/1.txt', 'haha');

输出信息


Warning: system() has been disabled for security reasons in /data/wwwroot/a/index.php on line 2

Warning: file_put_contents(): open_basedir restriction in effect. File(../b/1.txt) is not within the allowed path(s): (/data/wwwroot/a:/tmp/) in /data/wwwroot/a/index.php on line 3

Warning: file_put_contents(../b/1.txt): failed to open stream: Operation not permitted in /data/wwwroot/a/index.php on line 3

Nginx特殊场景配置

如果有特定的项目需要跨目录并且使用exec等命令的时候在对应的站点配置添加一行fastcgi_param  PHP_VALUE "";即可

# ...
        include        fastcgi_params;
        fastcgi_param  PHP_ADMIN_VALUE "";

注意:框架Yii、Laravel、Symfony等..., 只要是web目录不是在项目跟目录,都要单独在站点配置。

你如果对这篇博文感兴趣,你应该对这篇jailkit linux centos 限制用户活动范围和权限也感兴趣。