關鍵字 resin 虛擬主機 java.policy
提示
首先不要用root運行java.
本文適合啟用安全機制的resin.
啟用java的安全沙箱
默認resin是沒有啟用安全機制的,虛擬主機用戶可以隨意讀取系統文件,例如/etc/passwd等.
開啟安全機制很簡單,在resin.conf中的resin節點下加上:
<security-manager/>
重新運行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 |