全球主机交流论坛

标题: nginx完美解决同一服务上的站点WebShell访问限制问题 [打印本页]

作者: freebsd    时间: 2009-11-25 00:00
标题: nginx完美解决同一服务上的站点WebShell访问限制问题
转载请注明出自安兴软件工作室: 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
找到
  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配置
(, 下载次数: 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 编辑 ]
作者: freebsd    时间: 2009-11-25 00:01
ECMall 不是一般的破,搞了半天还是500,装不上,装上了又不能浏览,一肚子火,明天还要折腾

[ 本帖最后由 freebsd 于 2009-11-25 00:03 编辑 ]
作者: RyoKazami    时间: 2009-11-25 00:10
谢谢分享 ,明天测试。睡觉先……
作者: newers    时间: 2009-11-25 00:12
提示: 作者被禁止或删除 内容自动屏蔽
作者: freebsd    时间: 2009-11-25 00:22
今天整个下午到晚上都在搞 ECMall 2.1 整合Ucenter,真不是一般的破啊,修改了一些代码才勉强安装上,安装上了还是500   ,明天又得搞,
作者: gdtv    时间: 2009-11-25 01:33
占位,等有时间再试试
作者: cpuer    时间: 2009-11-25 10:03
标题: 回复 1# 的帖子
原来是改 fopen_wrappers.c 这里

学习了。
作者: cpuer    时间: 2009-11-25 10:03
标题: 回复 5# 的帖子
整合的话双方程序都有原因的。
作者: lemss    时间: 2009-11-25 10:53
非常感谢
作者: loveloli    时间: 2009-11-25 10:55
  学习了。
作者: freebsd    时间: 2009-11-25 10:58
标题: 回复 8# 的帖子
搞定了,三个问题。康盛ECMall 卖掉了,不如康盛在做的时候强啊
1、文档不清楚,有些目录及下面的必须全设置成777的,居然没有说明。
2、代码不友好,这些目录不能写入的时候,康盛的程序一般都是会提示你某某目录无法写入的,他家居然直接给你个500,让你摸不着头脑。
3、整合程序居然固定只能某个数据表前缀的才行,换个就不行,而且获取UC参数的程序段居然是有问题的,直接提交连不上UC,懒得分析程序了,直接把参数修改固定上去提交,总算通过了。
作者: cpuer    时间: 2009-11-25 11:25
标题: 回复 11# 的帖子
ECMall 的前景堪忧。
作者: junhan    时间: 2009-11-25 12:13
大家有测试好了的吗?
作者: RyoKazami    时间: 2009-11-26 16:12
我看了下 原稿:http://www.sectop.com/post/35.html 上面提到的方法,好像更方便点?

修改每个站点对应一个php-cgi端口就行了。

多个php-cgi主进程加载对应站点的conf文件,这样就完美解决了虚拟主机webshell能跨目录的问题吧?
作者: loveloli    时间: 2009-11-26 16:14
标题: 回复 14# 的帖子
但是这样子好像资源有点浪费了。
作者: RyoKazami    时间: 2009-11-26 16:26
这样啊,那LZ的方法也不错。官方每周更新,怎么这个不更新……
作者: junhan    时间: 2009-11-26 18:43
有人测试成功过吗?
我这还是不行`
作者: freebsd    时间: 2009-11-26 20:03
标题: 回复 14# 的帖子
那个方法不实用的
1、浪费资源,实际的IDC商不可能去用的,还不如nginx加apache后台
2、配置复杂,加大人力成本

好处是各站点基本上互不影响,适合个人小站
作者: freebsd    时间: 2009-11-26 20:05
标题: 回复 17# 的帖子
什么地方出错
作者: 火影    时间: 2009-11-26 20:39
技术强帖留名
作者: junhan    时间: 2009-11-26 21:47
原帖由 freebsd 于 2009-11-26 20:05 发表
什么地方出错


可以啦,原来多了一个;

;open_basedir = "/tmp/:/var/tmp/"
作者: gdtv    时间: 2010-1-6 16:07
顶上去,刚刚试了,可行
作者: cpuer    时间: 2010-1-6 16:17
标题: 回复 22# 的帖子
那nginx使用无忧了。
作者: qwe123    时间: 2010-1-8 12:53
做个记号哈
作者: pcboy128    时间: 2010-1-8 13:24
我也來做个记号 如果nginx加上web面板就灰常不错..
作者: 删除    时间: 2010-1-8 15:29
不用这么麻烦吧?直接open_basedir设置就可以的
作者: cpuer    时间: 2010-1-8 16:22
标题: 回复 26# 的帖子
直接不好使的,上传个webshell就可以发现问题了。
作者: gdtv    时间: 2010-1-8 18:02
标题: 回复 26# 的帖子
一台VPS只有一个网站的情况下很好使,否则,无效
作者: shy9000    时间: 2010-2-17 23:27
今天编译安装PHP了,应该OK了
作者: cpuer    时间: 2010-2-21 10:59
标题: 回复 28# 的帖子
是的,nginx特别。
作者: monface    时间: 2010-3-24 14:21
已经安装好了的vps,怎么把这段代码弄进去?
作者: gdtv    时间: 2010-3-24 14:34
标题: 回复 31# 的帖子
要重新编译php
作者: monface    时间: 2010-3-24 14:46
标题: 回复 32# 的帖子
必须重新编译,再安装啊?
作者: hantheme    时间: 2010-3-31 22:23
非常好啊
作者: eben    时间: 2010-3-31 22:29
学习了。
作者: edmin    时间: 2010-3-31 22:39
  收藏
作者: 大飞机    时间: 2010-6-24 23:43
高人啊 测试中··
作者: deak17    时间: 2010-6-24 23:58
这个必须支持
作者: eip    时间: 2010-7-1 22:31
按楼主方法,结果出现错误:

PHP Warning: Unknown: open_basedir restriction in effect. File() is not within the allowed path(s): (/www/:/tmp/) in Unknown on line 0

原来是eaccelerator-0.9.6.tar.bz2的bug:
http://www.sk7.cc/417.html
下载eaccelerator 0.9.6后先不要安装,解包后找到eaccelerator.c这个文件,打开第1156行,这样的:
if (PG(open_basedir) && php_check_open_basedir(realname TSRMLS_CC)) {
修改成:
if (PG(open_basedir) && php_check_open_basedir(file_handle->filename TSRMLS_CC)) {


另外php.ini必须如下配置:
php.ini配置:open_basedir = "/tmp/:/var/tmp/"

[ 本帖最后由 eip 于 2010-7-2 09:36 编辑 ]
作者: needvps    时间: 2010-7-6 11:09
原帖由 eip 于 2010-7-1 22:31 发表
按楼主方法,结果出现错误:

PHP Warning: Unknown: open_basedir restriction in effect. File() is not within the allowed path(s): (/www/:/tmp/) in Unknown on line 0

原来是eaccelerator-0.9.6.tar.bz2的bug:
ht ...


请问
open_basedir 这里能不能写成这样的
open_basedir = "/web/user/xxx.com/:/var/tmp/:/tmp/"
就是增加web目录,行不行?
作者: 鸿星尔克    时间: 2010-7-6 11:28
有人挖坟
作者: eip    时间: 2010-7-13 11:11
原帖由 needvps 于 2010-7-6 11:09 发表


请问
open_basedir 这里能不能写成这样的
open_basedir = "/web/user/xxx.com/:/var/tmp/:/tmp/"
就是增加web目录,行不行?


试过不行,只能写成:open_basedir = "/tmp/:/var/tmp/"
作者: spectrum    时间: 2010-7-20 23:48
提示: 作者被禁止或删除 内容自动屏蔽
作者: gdtv    时间: 2010-7-21 00:06
标题: 回复 43# 的帖子
我明确地告诉你:我在N台VPS和服务器上,按照楼主的方法,都成功了
作者: spectrum    时间: 2010-7-21 16:54
提示: 作者被禁止或删除 内容自动屏蔽
作者: needvps    时间: 2010-7-22 09:52
原帖由 gdtv 于 2010-7-21 00:06 发表
我明确地告诉你:我在N台VPS和服务器上,按照楼主的方法,都成功了


我发现还是有一些小问题,如果有些PHP程序写的不够严谨,就会出错




欢迎光临 全球主机交流论坛 (https://fd.vvwvv.eu.org/) Powered by Discuz! X3.4