全球主机交流论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

CeraNetworks网络延迟测速工具IP归属甄别会员请立即修改密码
查看: 27000|回复: 45

[经验] nginx完美解决同一服务上的站点WebShell访问限制问题

[复制链接]
发表于 2009-11-25 00:00:45 | 显示全部楼层 |阅读模式
转载请注明出自安兴软件工作室: http://www.anxsoft.com

以前曾发过一个解决的思路:
http://www.hostloc.com/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
找到
  1. /* {{{ php_check_open_basedir
  2. */
  3. PHPAPI int php_check_open_basedir_ex(const char *path, int warn TSRMLS_DC)
  4. {
  5.         /* Only check when open_basedir is available */
  6.         if (PG(open_basedir) && *PG(open_basedir)) {
  7.                 char *pathbuf;
  8.                 char *ptr;
  9.                 char *end;
  10.                 // add by anxsoft.com
  11.                 char *env_doc_root;
  12.                 if(PG(doc_root)){
  13.                         env_doc_root = estrdup(PG(doc_root));
  14.                 }else{
  15.                         env_doc_root = sapi_getenv("DOCUMENT_ROOT", sizeof("DOCUMENT_ROOT")-1 TSRMLS_CC);
  16.                 }
  17.                 if(env_doc_root){
  18.                         int        res_root = php_check_specific_open_basedir(env_doc_root, path TSRMLS_CC);
  19.                         efree(env_doc_root);
  20.                         if (res_root == 0) {
  21.                                 return 0;
  22.                         }
  23.                         if (res_root == -2) {
  24.                                 errno = EPERM;
  25.                                 return -1;
  26.                         }
  27.                 }
  28.                 // add by anxsoft.com


  29.                 pathbuf = estrdup(PG(open_basedir));

  30.                 ptr = pathbuf;

  31.                 while (ptr && *ptr) {
  32.                         end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
  33.                         if (end != NULL) {
  34.                                 *end = '\0';
  35.                                 end++;
  36.                         }

  37.                         if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) {
  38.                                 efree(pathbuf);
  39.                                 return 0;
  40.                         }

  41.                         ptr = end;
  42.                 }
  43.                 if (warn) {
  44.                         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));
  45.                 }
  46.                 efree(pathbuf);
  47.                 errno = EPERM; /* we deny permission to open it */
  48.                 return -1;
  49.         }

  50.         /* Nothing to check... */
  51.         return 0;
  52. }
  53. /* }}} */
复制代码
两个 add by anxsoft.com 中间的是修改加上去的

然后保存,退出。

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 编辑 ]

评分

参与人数 9威望 +80 收起 理由
Linode + 15 精品文章
gdtv -20 精品文章
loveloli + 5 成功了~
诡谲 + 5 精品文章
junhan + 10 精品文章 已测试成功!

查看全部评分

 楼主| 发表于 2009-11-25 00:01:41 | 显示全部楼层
ECMall 不是一般的破,搞了半天还是500,装不上,装上了又不能浏览,一肚子火,明天还要折腾

[ 本帖最后由 freebsd 于 2009-11-25 00:03 编辑 ]

评分

参与人数 1威望 +20 收起 理由
gdtv + 20 上面评错分了,这里加回

查看全部评分

发表于 2009-11-25 00:10:34 | 显示全部楼层
谢谢分享 ,明天测试。睡觉先……
发表于 2009-11-25 00:12:13 | 显示全部楼层
原帖由 RyoKazami 于 2009-11-25 00:10 发表
谢谢分享 ,明天测试。睡觉先……

等你的测试结果。
 楼主| 发表于 2009-11-25 00:22:50 | 显示全部楼层
今天整个下午到晚上都在搞 ECMall 2.1 整合Ucenter,真不是一般的破啊,修改了一些代码才勉强安装上,安装上了还是500   ,明天又得搞,

评分

参与人数 1威望 +20 收起 理由
gdtv + 20 上面评错分了,再给你加回

查看全部评分

发表于 2009-11-25 01:33:17 | 显示全部楼层
占位,等有时间再试试
发表于 2009-11-25 10:03:24 | 显示全部楼层

回复 1# 的帖子

原来是改 fopen_wrappers.c 这里

学习了。
发表于 2009-11-25 10:03:54 | 显示全部楼层

回复 5# 的帖子

整合的话双方程序都有原因的。
发表于 2009-11-25 10:53:32 | 显示全部楼层
非常感谢
发表于 2009-11-25 10:55:56 | 显示全部楼层
  学习了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|全球主机交流论坛

GMT+8, 2024-4-19 04:30 , Processed in 0.075896 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表