Aug 01 2008

令人头疼的Java SecurityManager

Category: 技术ssmax @ 15:25:56

今天又开始搞hadoop和hbase了,其实早几天就发现了hadoop的datanode连接master的时候,会自己转化hostname,因为很多主机的hostname都是随便设的,结果就是master通过这些hostname就访问不到datanode了。。。

今天看了一下源代码,在不修改的前提下没办法通过配置文件来修正这个错误。。。突然灵光闪过,它是默认通过InetAddress.getCanonicalHostName 来获取hostname的,而这个方法会调用SecurityManager的checkConnect方法来检查权限:

If there is a security manager, this method first calls its checkConnect method with the hostname and -1 as its arguments to see if the calling code is allowed to know the hostname for this IP address, i.e., to connect to the host. If the operation is not allowed, it will return the textual representation of the IP address.

如果加上一个默认的policy会不会就可行呢。。。结果就陷入了SecurityManager的泥潭里面了。。

n年前就知道有SecurityManager。。但是默认是不开的。。。这个就麻烦了,又要修改脚本,在执行java的时候加上

java -Djava.security.manager -Djava.security.policy=.java.policy classname

这样才会自动load,或者

java -Djava.security.manager classname

这样就会自动加载 ${user.home}/.java.policy

好的,就当它是加载了。。。

看一下policy文件的规则,写了一个

grant codeBase “file:${user.home}” {
        permission java.net.SocketPermission “*:-1”, “accept”;
};

给它一个accept权限,而没有其它权限,以为这样就可以啦。。。谁知道经过试验:

1、SocketPermission 有bug,不能在policy文件里面表达 <0 的port,但是java tmd就有用到 -1 权限。。。

     -1 竟然是代表 0-1这个范围的。。。试验了n个表达方式都不能表示负一,最后放弃。。。

2、只有grant,而没有revoke,如果只是要禁止一个程序做某一样东西,其它都不检查的话,暂时还没有找到方法做到,貌似就是自己扩展一个SecurityManager,然后用相反的方法来做就行了。。。

 

最后决定,还是改hadoop的源代码吧。。。。郁闷啊郁闷

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.