嵌入 Cassandra - 安全管理器问题
Embedding Cassandra - Security Manager issues
我正在尝试升级使用嵌入式 cassandra 2.1.1 的应用程序(时间差不多了!),但有问题的应用程序设置了自己的安全管理器。 Cassandra 3.11 似乎没有考虑这种可能性,只是尝试自行设置安全管理器,而不考虑可能已经存在一个(失败)。
2017-06-26T12:05:22,736 ERROR Thread-0 org.apache.cassandra.service.CassandraDaemon Exception encountered during startup
java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "createSecurityManager")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472) ~[?:1.8.0_101]
at java.security.AccessController.checkPermission(AccessController.java:884) ~[?:1.8.0_101]
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549) ~[?:1.8.0_101]
at java.lang.SecurityManager.<init>(SecurityManager.java:299) ~[?:1.8.0_101]
at org.apache.cassandra.cql3.functions.ThreadAwareSecurityManager.<init>(ThreadAwareSecurityManager.java:199) ~[?:3.11.0]
at org.apache.cassandra.cql3.functions.ThreadAwareSecurityManager.install(ThreadAwareSecurityManager.java:80) ~[?:3.11.0]
at org.apache.cassandra.service.CassandraDaemon.setup(CassandraDaemon.java:192) ~[?:3.11.0]
at org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:600) ~[?:3.11.0]
at org.jesterj.ingest.persistence.Cassandra.start(Cassandra.java:94) ~[?:?]
at org.jesterj.ingest.Main.startCassandra(Main.java:190) ~[?:?]
at org.jesterj.ingest.Main.lambda$main[=10=](Main.java:125) ~[?:?]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_101]
当我浏览 Cassandra 代码时,似乎没有任何配置检查来避免这种情况:
public static void install()
{
if (installed)
return;
System.setSecurityManager(new ThreadAwareSecurityManager());
ThreadAwareSecurityManager 中的评论似乎表明这是为了使用户定义的函数安全,但我不打算使用用户定义的函数,所以我非常乐意将其关闭,但我没有在代码中看到这样的选项。
static
{
//
// Use own security policy to be easier (and faster) since the C* has no fine grained permissions.
// Either code has access to everything or code has access to nothing (UDFs).
// This also removes the burden to maintain and configure policy files for production, unit tests etc.
这看起来很可疑,它需要先更改 Cassandra 的代码才能工作。有人有更好的主意吗?
作为参考,这是为了避免旧 cqlsh 在当前版本 python 中存在的问题:
https://github.com/nsoft/jesterj/issues/89
编辑: 尽管我之前安装了安全管理器,但找出了为什么会出现异常。事实证明,他们安装了一个策略,该策略使任何不是来自 url 以 'file' 开头的代码源的内容都失败。我的应用程序通过 one-jar 加载,因此我所有的代码源都有一个 url,例如:onejar:lib/docopt-0.6.1.jar。因此,当他们尝试安装自己的安全管理器时,他们 运行 违反了自己的政策而死了。
如果可能,您可以确保您现有的安全管理器允许它。可能像 this 这样的东西会导致问题,因为它将全局应用于 JVM。
或者你可以跳过它...这是一个更糟糕的选择,它可能会破坏东西,但你可以使用反射。
(inside whatever main class or something loaded very early in application)
static {
Field installed = ThreadAwareSecurityManager.class.getField("installed");
installed.setAccessible(true);
installed.set(null, true);
}
但这可能会在运行时引起问题,所以我会对其进行全面测试。
我是这样克服这个特殊问题的:
- 设置我的所有烫发政策(确保也覆盖 implies())
- 临时设置一个安全管理器忽略检查权限的调用()
Class.forName("org.apache.cassandra.cql3.functions.ThreadAwareSecurityManager")
这会导致 class 初始化并安装有问题的策略
- 重新设置我的所有烫发政策
- 设置普通的 SecurityManager()
这阻止了上面的堆栈跟踪,并导致了一个不同的问题,所以我将在这里结束这个问题,并在需要时打开另一个问题,但作为参考,下一个问题仍然与 ThreadAwareSecurityManager 相关...
java.lang.ClassCastException: org.apache.logging.slf4j.Log4jLogger cannot be cast to ch.qos.logback.classic.Logger
at org.apache.cassandra.cql3.functions.ThreadAwareSecurityManager.install(ThreadAwareSecurityManager.java:92) ~[cassandra-all-3.11.0.jar:3.11.0]
at org.apache.cassandra.service.CassandraDaemon.setup(CassandraDaemon.java:192) ~[cassandra-all-3.11.0.jar:3.11.0]
at org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:600) ~[cassandra-all-3.11.0.jar:3.11.0]
at org.jesterj.ingest.persistence.Cassandra.start(Cassandra.java:94) ~[main.jar:?]
at org.jesterj.ingest.Main.startCassandra(Main.java:198) ~[main.jar:?]
at org.jesterj.ingest.Main.lambda$main[=10=](Main.java:132) ~[main.jar:?]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_101]
我正在尝试升级使用嵌入式 cassandra 2.1.1 的应用程序(时间差不多了!),但有问题的应用程序设置了自己的安全管理器。 Cassandra 3.11 似乎没有考虑这种可能性,只是尝试自行设置安全管理器,而不考虑可能已经存在一个(失败)。
2017-06-26T12:05:22,736 ERROR Thread-0 org.apache.cassandra.service.CassandraDaemon Exception encountered during startup
java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "createSecurityManager")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472) ~[?:1.8.0_101]
at java.security.AccessController.checkPermission(AccessController.java:884) ~[?:1.8.0_101]
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549) ~[?:1.8.0_101]
at java.lang.SecurityManager.<init>(SecurityManager.java:299) ~[?:1.8.0_101]
at org.apache.cassandra.cql3.functions.ThreadAwareSecurityManager.<init>(ThreadAwareSecurityManager.java:199) ~[?:3.11.0]
at org.apache.cassandra.cql3.functions.ThreadAwareSecurityManager.install(ThreadAwareSecurityManager.java:80) ~[?:3.11.0]
at org.apache.cassandra.service.CassandraDaemon.setup(CassandraDaemon.java:192) ~[?:3.11.0]
at org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:600) ~[?:3.11.0]
at org.jesterj.ingest.persistence.Cassandra.start(Cassandra.java:94) ~[?:?]
at org.jesterj.ingest.Main.startCassandra(Main.java:190) ~[?:?]
at org.jesterj.ingest.Main.lambda$main[=10=](Main.java:125) ~[?:?]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_101]
当我浏览 Cassandra 代码时,似乎没有任何配置检查来避免这种情况:
public static void install()
{
if (installed)
return;
System.setSecurityManager(new ThreadAwareSecurityManager());
ThreadAwareSecurityManager 中的评论似乎表明这是为了使用户定义的函数安全,但我不打算使用用户定义的函数,所以我非常乐意将其关闭,但我没有在代码中看到这样的选项。
static
{
//
// Use own security policy to be easier (and faster) since the C* has no fine grained permissions.
// Either code has access to everything or code has access to nothing (UDFs).
// This also removes the burden to maintain and configure policy files for production, unit tests etc.
这看起来很可疑,它需要先更改 Cassandra 的代码才能工作。有人有更好的主意吗?
作为参考,这是为了避免旧 cqlsh 在当前版本 python 中存在的问题:
https://github.com/nsoft/jesterj/issues/89
编辑: 尽管我之前安装了安全管理器,但找出了为什么会出现异常。事实证明,他们安装了一个策略,该策略使任何不是来自 url 以 'file' 开头的代码源的内容都失败。我的应用程序通过 one-jar 加载,因此我所有的代码源都有一个 url,例如:onejar:lib/docopt-0.6.1.jar。因此,当他们尝试安装自己的安全管理器时,他们 运行 违反了自己的政策而死了。
如果可能,您可以确保您现有的安全管理器允许它。可能像 this 这样的东西会导致问题,因为它将全局应用于 JVM。
或者你可以跳过它...这是一个更糟糕的选择,它可能会破坏东西,但你可以使用反射。
(inside whatever main class or something loaded very early in application)
static {
Field installed = ThreadAwareSecurityManager.class.getField("installed");
installed.setAccessible(true);
installed.set(null, true);
}
但这可能会在运行时引起问题,所以我会对其进行全面测试。
我是这样克服这个特殊问题的:
- 设置我的所有烫发政策(确保也覆盖 implies())
- 临时设置一个安全管理器忽略检查权限的调用()
Class.forName("org.apache.cassandra.cql3.functions.ThreadAwareSecurityManager")
这会导致 class 初始化并安装有问题的策略- 重新设置我的所有烫发政策
- 设置普通的 SecurityManager()
这阻止了上面的堆栈跟踪,并导致了一个不同的问题,所以我将在这里结束这个问题,并在需要时打开另一个问题,但作为参考,下一个问题仍然与 ThreadAwareSecurityManager 相关...
java.lang.ClassCastException: org.apache.logging.slf4j.Log4jLogger cannot be cast to ch.qos.logback.classic.Logger
at org.apache.cassandra.cql3.functions.ThreadAwareSecurityManager.install(ThreadAwareSecurityManager.java:92) ~[cassandra-all-3.11.0.jar:3.11.0]
at org.apache.cassandra.service.CassandraDaemon.setup(CassandraDaemon.java:192) ~[cassandra-all-3.11.0.jar:3.11.0]
at org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:600) ~[cassandra-all-3.11.0.jar:3.11.0]
at org.jesterj.ingest.persistence.Cassandra.start(Cassandra.java:94) ~[main.jar:?]
at org.jesterj.ingest.Main.startCassandra(Main.java:198) ~[main.jar:?]
at org.jesterj.ingest.Main.lambda$main[=10=](Main.java:132) ~[main.jar:?]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_101]