通过修改PHP源代码解决Nginx下WebShell跨站的问题

Nginx / Lighttpd + PHP FastCGI的方式正在被越来越多的网站应用,其中让需要虚拟主机支持的用户最烦心的一件事情莫过于站点权限隔离。 目前无论是spawn-cgi或者是php-fpm的方式,都无法动态转变执行用户。尽管可以通过给不同网站以不同的用户身份执行FastCGI,但这也同样失去了FastCGI统一管理的优势,需要为每个网站保留足够的处理进程而不是整体规划。

Google搜之有两个比较广为流传的方法,其中最完美的莫过于直接修改PHP源代码,对打开目录进行鉴权(搜出来的资料最早是anxsoft.com提供的代码)。

因为需要更改php源程序后,重新编译php。在使用fpm方式安装时,打补丁过程中会修改php的文件,所以需要在打完fpm补丁后再修改php源程序。

 


tar zxvf php-5.2.14.tar.gz
gzip -cd php-5.2.14-fpm-0.5.14.diff.gz | patch -d php-5.2.14 -p1
cd php-5.2.14/

vi main/fopen_wrappers.c
 



找到php_check_open_basedir_ex方法,在char *end;和pathbuf = estrdup(PG(open_basedir));之间插入以下的代码:

 


char path_copy[MAXPATHLEN];
int path_len;
path_len = strlen(path);
if (path_len >= MAXPATHLEN) {
errno = EPERM;
return -1;
}
if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
memcpy(path_copy, path, path_len+1);
while (path_len > 1 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
path_copy[path_len] = '\0';
path = (const char *)&path_copy;
}

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;
}
}

 



然后编译安装php。

并php.ini的open_basedir配置
open_basedir = "/tmp/:/var/tmp/"

这样就彻底解决了,webshell跨站点目录访问问题。


 

你可能感兴趣的:(Google,源代码,动态,虚拟主机,源程序)