Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2551848
  • 博文数量: 709
  • 博客积分: 12251
  • 博客等级: 上将
  • 技术积分: 7905
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-17 00:00
个人简介

实现有价值的IT服务

文章存档

2012年(7)

2011年(147)

2009年(3)

2008年(5)

2007年(74)

2006年(431)

2005年(42)

分类: Java

2006-07-24 13:50:29

关键字 resin 虚拟主机 java.policy


提示
首先不要用root运行java.

本文适合启用安全机制的resin.

启用java的安全沙箱
默认resin是没有启用安全机制的,虚拟主机用户可以随意读取系统文件,例如/etc/passwd等.

开启安全机制很简单,在resin.conf中的resin节点下加上:



重新运行resin,默认的安全沙箱就打开了,不过此时会发现什么程序都运行不了了.此时用的是java默认提供的java.policy.

浏览resin的文档,提供了一个简单的policy http://www.caucho.com/resin-3.0/security/securitymanager.xtp .

(建议粗略阅读一下 http://www.caucho.com/resin-3.0/security/index.xtp 的所有章节 )




了解安全沙箱


默认的policy或者resin提供的policy是远远不够的,所以要定义自己的policy.

在开始之前,也许你应该阅读一下java doc中的security的文档,了解一下Permission的机制和类型.
本文不对policy的语法和Permission运行机制做解释.
本文也不对用户签名做解释,因为除非特殊要求,也是没有这个要求的.

除了java本身提供的Permission,一些类库也提供了一些Permission,例如ognl本身也提供了一个,如果用到这些类库,也要进行相应的设置.


默认的语法类似:

grant codeBase "file:/home/testuser/-" {
permission java.io.FilePermission "/tmp/abc", "read";
};





java提供的权限类型有:

java.security.AllPermission 所有权限的集合
java.security.SecurityPermission policy安全控制方面的
java.security.UnresolvedPermission
java.awt.AWTPermission
java.io.FilePermission 文件权限,包括读写,删除,执行
java.io.SerializablePermission 序列化(次第读写)
java.lang.reflect.ReflectPermission 反射
java.lang.RuntimePermission 运行时

java.net.NetPermission 网络
java.net.SocketPermission
java.sql.SQLPermission 数据库sql
java.util.PropertyPermission 系统/环境属性
java.util.logging.LoggingPermission 日志控制
javax.net.ssl.SSLPermission 安全连接
javax.security.auth.AuthPermission 认证
javax.security.auth.PrivateCredentialPermission
javax.security.auth.kerberos.DelegationPermission
javax.security.auth.kerberos.ServicePermission
javax.sound.sampled.AudioPermission

目录匹配提示:
*表示所有文件
-表示所有文件及其子目录下的文件



设置resin的policy


要启用自定义的policy,在/etc/init.d/resin中修改EXE对应的一行,加入参数:
EXE="$RESIN_HOME/bin/httpd.sh -Djava.security.policy=/web/resin/policy/resin.policy "

你的policy保存在resin目录下的resin.policy,或者其他地方也可,但是要有适当的权限.


policy设置之路


resin或者说java的policy设置起来非常麻烦,总之没有直观的方法.我的方法就是设置一个,重新启动resin,访问页面,然后看日志,然后修改policy.

其中很多地方有很多疑问,还没有得到解决,一些policy明明看到已经包含在别的policy里,但是又必须单独设置,非常奇怪.

总之觉得是对底层运行机制不熟悉造成的吧.

如果有熟悉的人,不妨指点一二.

最后获取的resin.policy如下:

// java和resin类赋予所有权限

grant codeBase "file:${java.home}/lib/-" {
permission java.security.AllPermission;
};

grant codeBase "file:${java.home}/jre/lib/-" {
permission java.security.AllPermission;
};

grant codeBase "file:${java.home}/lib/ext/-" {
permission java.security.AllPermission;
};

grant codeBase "file:${java.home}/jre/lib/ext/-" {
permission java.security.AllPermission;
};

grant codeBase "file:${resin.home}/lib/-" {
permission java.security.AllPermission;
};


// 所有用户拥有的权限.

grant {
//read all property 可以读所有属性
permission java.util.PropertyPermission "*", "read";

// Permission "enableSubstitution"
permission java.io.SerializablePermission "enableSubstitution";

//reflect 可以使用反射,spring,hibernate很多地方都用了反射
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";

//runtime 这个很多,自己一个一个理解吧,根据程序不同,需要增减
permission java.lang.RuntimePermission "accessClassInPackage.*";
permission java.lang.RuntimePermission "getClassLoader";
permission java.lang.RuntimePermission "accessDeclaredMembers";
permission java.lang.RuntimePermission "modifyThreadGroup";
permission java.lang.RuntimePermission "setContextClassLoader";
permission java.lang.RuntimePermission "setIO";
permission java.lang.RuntimePermission "stopThread";
permission java.lang.RuntimePermission "createClassLoader";
permission java.lang.RuntimePermission "getProtectionDomain";
permission java.lang.RuntimePermission "defineClassInPackage";

//如果用到jce
permission java.security.SecurityPermission "putProviderProperty.SunJCE";
permission java.security.SecurityPermission "insertProvider.SunJCE";

//用到日志,需要设置
permission java.util.logging.LoggingPermission "control";

//访问1024以上的端口,如果程序没用到,可以删除
permission java.net.SocketPermission "localhost:1024-", "listen";

// Required for OpenJMX
permission java.lang.RuntimePermission "getAttribute";

// Allow read of JAXP compliant XML parser debug
permission java.util.PropertyPermission "jaxp.debug", "read";

//ognl invoke if use ognl 如果用到ognl,必须加上
permission ognl.OgnlInvokePermission "invoke.*";

};

grant {

//access mysql,if should access other database,add them 访问mysql的
permission java.net.SocketPermission "localhost:3306","connect";

//why read? 这个有疑问的,不加不行啊
permission java.io.FilePermission "${resin.home}/-", "read";
permission java.io.FilePermission "${java.home}/-", "read";

//tmp file,don't worry delete,write because you only can modify your files. 这个是读写临时文件的
permission java.io.FilePermission "/tmp/-","read,write,delete";
permission java.io.FilePermission "/tmp","read,write,delete";

};


//如果有多个虚拟主机,一些目录可以合并到一个目录,不用写多个了
grant {
//why? don't know!!! (both in classpath) 因为classpath里有这个,就得加上?
permission java.io.FilePermission ".","read";

// 因为classpath里有这个,就得加上?
permission java.io.FilePermission "/jdk5/lib/tools.jar","read";

//should have read ,who read?! 这个奇怪哦
permission java.io.FilePermission "/home/testuser/html", "read";
permission java.io.FilePermission "/home/testuser/html/-", "read";

//for resin temp-dir and jsp compile(work-dir) 临时目录
permission java.io.FilePermission "/home/testuser/worktmp/-", "read,write,delete";

//why resin will delete files for jsp compile in this directory? don't know 这个不知道,反正特奇怪
permission java.io.FilePermission "/home/testuser/html/_jsp/-", "read,write,delete";

};


//for one user 对一个用户的特殊设置
grant codeBase "file:/home/testuser/-" {
//这个用户可以读写,删除自己的文件,例如用程序生成静态文件.
permission java.io.FilePermission "/home/testuser/-", "read,write,delete";
};






经过一番折磨,我的网站终于在resin下运行起来了,尽管还有很多疑问!

如果你熟悉这些问题,请告诉我 :)








  除经特别注明外,本文章版权归JScud Develop团队或其作者所有.
署名,非商业用途,保持一致. scud(飞云小侠) JScud Develop
阅读(777) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~