|  | 
 
| 转载请注明出自安兴软件工作室: http://www.anxsoft.com 
 以前曾发过一个解决的思路:
 http://fd.vvwvv.eu.org/viewthrea ... ighlight=%2Bfreebsd
 
 当时用phpspy2008测试权限,浏览等,都没有什么问题,但是没有在接近实际的环境中测试过,后来网友们反映还是经常有出现No input file specified.
 后我本人又重新测试了一下,发现web服务器刚启动时正常,过了几分钟以后随机性的会出现 No input file specified. 或者返回404。
 
 心情很是郁闷,加上近几天自己的网站也准备加强一下安全措施,于是干脆着手修改php的源代码解决,经过几个小时的研究,终于完美解决了这个问题,而且由于本办法是修改php来实现的,故使用范围应该不限于nginx,也可以应用到其他的web服务器上。
 
 现将修改办法公布如下,以CentOS 5.3   php 2.5.10 nginx 0.8.27为例
 
 wget http://www.php.net/get/php-5.2.10.tar.gz/from/this/mirror
 wget http://php-fpm.org/downloads/php-5.2.10-fpm-0.5.13.diff.gz
 tar zxvf php-5.2.10.tar.gz
 gzip -cd php-5.2.10-fpm-0.5.13.diff.gz | patch -d php-5.2.10 -p1 //如果你用补丁的话先打补丁再改比较妥当,我没检查过补丁有没动这个文件
 cd php-5.2.10/
 ./configure --prefix=...............此处省略N多配置选项
 vi main/fopen_wrappers.c
 找到
 两个 add by anxsoft.com 中间的是修改加上去的复制代码/* {{{ php_check_open_basedir
 */
PHPAPI int php_check_open_basedir_ex(const char *path, int warn TSRMLS_DC)
{
        /* Only check when open_basedir is available */
        if (PG(open_basedir) && *PG(open_basedir)) {
                char *pathbuf;
                char *ptr;
                char *end;
                // add by anxsoft.com
                char *env_doc_root;
                if(PG(doc_root)){
                        env_doc_root = estrdup(PG(doc_root));
                }else{
                        env_doc_root = sapi_getenv("DOCUMENT_ROOT", sizeof("DOCUMENT_ROOT")-1 TSRMLS_CC);
                }
                if(env_doc_root){
                        int        res_root = php_check_specific_open_basedir(env_doc_root, path TSRMLS_CC);
                        efree(env_doc_root);
                        if (res_root == 0) {
                                return 0;
                        }
                        if (res_root == -2) {
                                errno = EPERM;
                                return -1;
                        }
                }
                // add by anxsoft.com
                pathbuf = estrdup(PG(open_basedir));
                ptr = pathbuf;
                while (ptr && *ptr) {
                        end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
                        if (end != NULL) {
                                *end = '\0';
                                end++;
                        }
                        if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) {
                                efree(pathbuf);
                                return 0;
                        }
                        ptr = end;
                }
                if (warn) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "open_basedir restriction in effect. File(%s) is not within the allowed path(s): (%s)", path, PG(open_basedir));
                }
                efree(pathbuf);
                errno = EPERM; /* we deny permission to open it */
                return -1;
        }
        /* Nothing to check... */
        return 0;
}
/* }}} */
 然后保存,退出。
 
 make ZEND_EXTRA_LIBS='-liconv'
 make install
 
 OK,接下来该干嘛干嘛去~~~
 
 php.in的open_basedir配置
 
  phpini.jpg
(22.53 KB, 下载次数: 58) 
 nginx的配置无须做任何变动(无须添加 ../../../../../ 等繁琐的东西),完美限制在网站的根目录上,无法访问其他同一服务器上网站的文件。
 
 另外出现 no input files 绝不是网上某人说的原因。
 
 
 nginx在80端口接受到访问请求后,会把请求转发给9000端口的php-cgi进行处理而如果修改php.ini中open_basedir= ../../../../../ ,针对两个不同的网站,www.a.com , www.b.com都会把请求发送给9000处理,而如果先访问www.a.com那么../../../../../就会变成A网站的根目录地址,然后这时候如果你访问www.b.com,那么open_basedir仍然是A网站的根目录,但是对于B来说,又是不允许访问的,所以就造成了,第二个站点打开以后会出现no input files
 代码清楚的表明 open_basedir 每次请求都是重新计算路径的,会出现所说的问题,是因为php执行的时候经常会改变当前路径,造成最后 ../../../../../ 以后路径不对,而不是请求一次open_basedir就固定了。
 
 [ 本帖最后由 freebsd 于 2010-1-13 21:31 编辑 ]
 | 
 评分
查看全部评分
 |