文档章节

PHP7中用opcache.file_cache导出脚本opcode实现源代码保护

eechen
 eechen
发布于 2015/12/07 00:55
字数 920
阅读 8841
收藏 46

停止php-fpm(apache同理):
sudo /png/php/7.0.0/png_fpm stop

创建opcode缓存目录:
mkdir -m 777 /png/php/opcache_file_cache

在php.ini中配置:
zend_extension=/png/php/7.0.0/lib/php/extensions/no-debug-non-zts-20151012/opcache.so
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
;opcache不保存注释,减少opcode大小
opcache.save_comments=0
;关闭PHP文件时间戳验证
opcache.validate_timestamps=Off
;每60秒验证php文件时间戳是否更新
;opcache.revalidate_freq=60
opcache.fast_shutdown=1
;注意,PHP7下命令行执行的脚本也会被 opcache.file_cache 缓存.
opcache.enable_cli=1
;设置不缓存的黑名单
;opcache.blacklist_filename=/png/php/opcache_blacklist
opcache.file_cache=/png/php/opcache_file_cache
opcache.file_cache_only=0
opcache.enable=On

备份原来项目(以phpMyAdmin为例):
cp -R /png/www/example.com/public_html/app/pma /png/www/example.com/public_html/app/pma.bak

执行opcache_compile_file.php导出PHP脚本对应的opcode:
sudo /png/php/7.0.0/bin/php /png/www/example.com/public_html/app/opcache_compile_file.php
opcache_compile_file.php 内容如下:

<?php
function getfiles( $path , &$files = array() ) {
	if ( !is_dir( $path ) ) return null;
	$handle = opendir( $path );
	while ( false !== ( $file = readdir( $handle ) ) ) {
		if ( $file != '.' && $file != '..' ) {
			$path2 = $path . '/' . $file;
			if ( is_dir( $path2 ) ) {
				getfiles( $path2 , $files );
			} else {
				if ( preg_match( '%\.php$%' , $file ) ) {
					$files[] = $path2;
				}
			}
		}
	}
	return $files;
}
// 获取指定目录及其子目录下的所有PHP文件
$files = getfiles('/png/www/example.com/public_html/app/pma');
foreach($files as $file){
	opcache_compile_file($file); //编译PHP文件生成opcode
	file_put_contents($file, ''); //清空原来的PHP脚本
	echo $file."\n";
}
echo 'Total PHP Files: '.count($files)."\n";

或者使用PHP的SPL库里提供的递归目录迭代器RecursiveDirectoryIterator实现递归编译PHP:

<?php
opcache_compile_files('/png/www/example.com/public_html/app/pma');
function opcache_compile_files($dir) {
	foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)) as $v) {
		if(!$v->isDir() && preg_match('%\.php$%', $v->getRealPath())) {
			opcache_compile_file($v->getRealPath());
			echo $v->getRealPath()."\n";
		}
	}
}

把缓存目录所有者设为php-fpm运行用户,我这里是png:
sudo chown -R png:png /png/php/opcache_file_cache/

启动php-fpm:
sudo /png/php/7.0.0/png_fpm start
访问phpMyAdmin:
http://www.example.com/app/pma/

phpMyAdmin的PHP文件一一对应的opcode(后缀为.php.bin)生成在:
/png/php/opcache_file_cache/xxx/png/www/example.com/public_html/app/pma
其中xxx是一个32位的md5编码的字符串.
部署到目标服务器的时候,需要保留项目中内容被清空的PHP脚本.
而且路径一定要对应导出opcode时的路径,文中的就是:
/png/www/example.com/public_html/app/pma

另外,PHP还可以使用函数php_strip_whitespace()删除PHP源码中的注释和空格.

后话:
opcache.file_cache是PHP7对hhvm.repo.central.path的反击,鸟哥威武!
opcache.file_cache对比PHP5时代APC的apc_bin_dumpfile和apc_bin_loadfile来说,
导出和导入操作都由opcache完成,显然ZendOpcache比APC更加自动化.
那个md5串由 PHP_VERSION / ZEND_EXTENSION_BUILD_ID / ZEND_BIN_ID 确定:

php-src/ext/opcache/zend_file_cache.c: zend_file_cache_get_bin_file_path ZCG(system_id)
php-src/ext/opcache/ZendAccelerator.c: accel_gen_system_id ZCG(system_id) 
#define ZEND_EXTENSION_BUILD_ID "API" ZEND_TOSTR(ZEND_EXTENSION_API_NO) ZEND_BUILD_TS ZEND_BUILD_DEBUG ZEND_BUILD_SYSTEM ZEND_BUILD_EXTRA
#define ZEND_BIN_ID "BIN_" ZEND_TOSTR(SIZEOF_CHAR) ZEND_TOSTR(SIZEOF_INT) ZEND_TOSTR(SIZEOF_LONG) ZEND_TOSTR(SIZEOF_SIZE_T) ZEND_TOSTR(SIZEOF_ZEND_LONG) ZEND_TOSTR(ZEND_MM_ALIGNMENT)

因为Ubuntu上编译的PHP7,打包依赖库后放到CentOS上运行,这个md5串是相同的.
可以肯定的是,Linux上导出的opcode不能放到Windows上运行,反之也是如此.

Beast加密过的PHP文件,也一样能看到PHP文件对应的opcode,
因为Beast解密后,还是一样需要调用zend_compile_file生成页面的opcode,
而opcode是可以用VLD(Vulcan Logic Disassembler)这类PECL扩展查看的.
php -dvld.active=1 -S 127.0.0.1:8080
curl http://127.0.0.1:8080/
也就是说,PHP脚本加密能够避免脚本被恶意篡改,但脚本里的数据仍然是可见的.
所以,文中的opcache.file_cache用来保护代码逻辑应该还是可以的,
但不能确保里面定义的量的安全,比如加密密钥.存也可以,但防君子不防小人,门槛高点而已.

Zend Guard和ionCube加密的PHP脚本可以用DeZender/De-ionCube解密:
http://dezender.net/
Java字节码和Android APK可以用Java Decompiler反编译:
http://jd.benow.ca/
Python脚本可以编译成pyc文件,不过pyc文件也很容易被反编译.
所以包括opcache.file_cache这样的代码保护,也只能防君子不防小人.

 

© 著作权归作者所有

共有 人打赏支持
eechen

eechen

粉丝 990
博文 107
码字总数 55962
作品 1
深圳
私信 提问
加载中

评论(27)

eechen
eechen

引用来自“Tai7sy”的评论

一处错误:
必须设置 file_only=0(关闭), 否则 opcache_compile_file 无法调用
php --ri 'Zend OPcache' 并没有你说的 file_only 配置项.
你说的应该是 opcache.file_cache_only.
刚才测试了PHP 7.1,确实需要配置:
opcache.file_cache_only=0
否则会提示:
Notice: Zend OPcache seems to be disabled, can't compile file
T
Tai7sy
一处错误:
必须设置 file_only=0(关闭), 否则 opcache_compile_file 无法调用
天睿云计算
天睿云计算

引用来自“eechen”的评论

引用来自“天睿云计算”的评论

zend 加密软件 不再支持php7了
ioncube提供的PHP脚本加密服务还是支持PHP7的,甚至支持ARM架构的Linux,比如树莓派的Raspbian(基于Debian ARM).

@eechen 嗯,ioncube10还在开发中
eechen
eechen

引用来自“天睿云计算”的评论

zend 加密软件 不再支持php7了
ioncube提供的PHP脚本加密服务还是支持PHP7的,甚至支持ARM架构的Linux,比如树莓派的Raspbian(基于Debian ARM).
天睿云计算
天睿云计算
zend 加密软件 不再支持php7了
SaFlyORG
SaFlyORG
我现在用的apache + mod_php,请问是不是要换成 apache + php-fpm
SaFlyORG
SaFlyORG
已经chown -R apache:apache 目标目录
SaFlyORG
SaFlyORG
@eechen bin生成成功了,并且php -f 某个php文件可以正常执行。但通过http方式访问就是空白页。请问是apache的原因么?
SaFlyORG
SaFlyORG

引用来自“eechen”的评论

@AbyssConG 你需要确保你的程序(httpd)对opcache.file_cache目录有写权限.
把opcache.file_cache目录的所有者设为httpd的运行用户.
已经成功了,十分感谢大神89
SaFlyORG
SaFlyORG

引用来自“eechen”的评论

@AbyssConG 你需要确保你的程序(httpd)对opcache.file_cache目录有写权限.
把opcache.file_cache目录的所有者设为httpd的运行用户.
感谢回复:) 我把目录权限设为777,可还是不能成功。。。是不是要在apache关闭的情况下,php -f opcache_compile_file.php 才能成功?
PHP开发Linux桌面应用和Android应用思路

PHP7中用opcache.file_cache导出脚本opcode实现源代码保护 http://my.oschina.net/eechen/blog/539995 下载PHPDroid: 基于WebView和PHP内置HTTP服务器开发Android应用 http://my.oschina.ne......

eechen
2015/09/05
0
14
php7性能优化

之前一直使用的PHP版本都是6.5/6.6的,这次的项目开发要求使用PHP7,在网上大概看了下,发现PHP7的性能较之前相比提升了很多,所以使用PHP7我也没啥意见,欣然接受。 今天温州一家客户做活动...

西红柿炒肉
2017/11/09
0
0
【PHP7源码分析】PHP7语言的执行原理

我们常用的高级语言有很多种,比较出名的有CC++、Python、 PHP、Go、Pascal等。而这些语言根据运行的方式不同,大体分为两种:编译型语言和解释型语言。 其中,编译型语言包括CC++、Pascal、...

陈雷_顺风车
08/16
0
0
PHP历史之3:秣兵历马的PHP7-王者归来

提起PHP7,就不得不提到源自FB的HHVM,据说安装了这种优化器,可以高效的PHP运行环境提升PHP性能9倍以上 当然PHP7已经超过了这种性能。 伴随着PHP 7的发布,这几天关于PHP 7性能和兼容性成了大...

ccpit2b2c
06/26
0
0
PHP7优化提高性能的几个Tips

PHP7已经发布了, 作为PHP10年来最大的版本升级, 最大的性能升级, PHP7在多放的测试中都表现出很明显的性能提升, 然而, 为了让它能发挥出最大的性能, 我还是有几件事想提醒下. 1. Opcache 记得...

English0523
2015/12/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

降压变换器 Buck

特点 输入输出极性相同。 工作过程 在 MOS 导通时,输入电源通过 L 和 C 滤波后向负载端提供电流;当 MOS 断开后,L 通过二极管续流,保持负载电流连续。输出电压因为占空比的作用,不会超过...

colinux
今天
1
0
Apache日志不记录访问静态文件,访问日志切割,静态元素过期时间设置

Apache配置不记录访问静态文件的日志 网站大多元素为静态文件,如图片、css、js等,这些元素可以不用记录 vhost原始配置 <VirtualHost *:80> ServerAdmin test@163.com DocumentRoo...

野雪球
今天
3
0
聊聊storm的ICommitterTridentSpout

序 本文主要研究一下storm的ICommitterTridentSpout ICommitterTridentSpout storm-core-1.2.2-sources.jar!/org/apache/storm/trident/spout/ICommitterTridentSpout.java public interface......

go4it
今天
4
0
Ubuntu常用操作

查看端口号 netstat -anp |grep 端口号 查看已使用端口情况 netstat -nultp(此处不用加端口号) netstat -anp |grep 82查看82端口的使用情况 查找被占用的端口: netstat -tln netstat -tl...

hc321
昨天
3
0
网站cdn的静态资源突然访问变的缓慢,问题排查流程

1.首先我查看了一下是否自己的网络问题,通过对比其他资源的访问速度和下载速度,确认不是 2.通过ping 和 tracert 判断cdn域名能否正常访问,(最后回想感觉这一步可以省略,因为每次最终能访...

小海bug
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部