如何在Tomcat 6中明智地配置安全策略

时间:2010-04-15 12:48:20

标签: java tomcat ubuntu tomcat6 securitymanager

我正在使用Tomcat 6.0.24,为Ubuntu Karmic打包。 Ubuntu的Tomcat软件包的默认安全策略非常严格,但看起来很简单。在/var/lib/tomcat6/conf/policy.d中,有多种文件可以建立默认策略。

值得注意的是:

  • 我根本没有更改库存tomcat安装 - 没有新的jar进入其常见的lib目录,没有server.xml更改等。将.war文件放入webapps directory是唯一的部署操作。
  • 我正在部署的Web应用程序失败,在此默认策略下有数千个拒绝访问权限(由于-Djava.security.debug="access,stack,failure"系统属性而报告给日志)。
  • 完全关闭安全管理器不会导致任何错误和正确的应用功能

我想要做的是将特定于应用程序的安全策略文件添加到policy.d目录,这似乎是推荐的做法。我将此添加到policy.d/100myapp.policy(作为起点 - 我希望最终将授予的权限减少到应用程序实际需要的权限):

grant codeBase "file:${catalina.base}/webapps/ROOT.war" {
  permission java.security.AllPermission;
};

grant codeBase "file:${catalina.base}/webapps/ROOT/-" {
  permission java.security.AllPermission;
};

grant codeBase "file:${catalina.base}/webapps/ROOT/WEB-INF/-" {
  permission java.security.AllPermission;
};

grant codeBase "file:${catalina.base}/webapps/ROOT/WEB-INF/lib/-" {
  permission java.security.AllPermission;
};

grant codeBase "file:${catalina.base}/webapps/ROOT/WEB-INF/classes/-" {
  permission java.security.AllPermission;
};

请注意试图找到正确的codeBase声明时的颠簸。我认为这可能是我的根本问题。

无论如何,以上(实际上只有前两个授权似乎有效)几乎有效:成千上万的访问拒绝消失了,而我只留下了一个。相关堆栈跟踪:

java.security.AccessControlException: access denied (java.io.FilePermission /var/lib/tomcat6/webapps/ROOT/WEB-INF/classes/com/foo/some-file-here.txt read)
  java.security.AccessControlContext.checkPermission(AccessControlContext.java:323)
  java.security.AccessController.checkPermission(AccessController.java:546)
  java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
  java.lang.SecurityManager.checkRead(SecurityManager.java:871)
  java.io.File.exists(File.java:731)
  org.apache.naming.resources.FileDirContext.file(FileDirContext.java:785)
  org.apache.naming.resources.FileDirContext.lookup(FileDirContext.java:206)
  org.apache.naming.resources.ProxyDirContext.lookup(ProxyDirContext.java:299)
  org.apache.catalina.loader.WebappClassLoader.findResourceInternal(WebappClassLoader.java:1937)
  org.apache.catalina.loader.WebappClassLoader.findResource(WebappClassLoader.java:973)
  org.apache.catalina.loader.WebappClassLoader.getResource(WebappClassLoader.java:1108)
  java.lang.ClassLoader.getResource(ClassLoader.java:973)

我非常确信触发拒绝的实际文件是无关紧要的 - 它只是我们检查可选配置参数的一些属性文件。有趣的是:

  1. 在此上下文中不存在
  2. 文件不存在的事实最终会引发安全异常,而不是java.io.File.exists()只返回false(尽管我认为这只是读取权限的语义问题)。
  3. 另一种解决方法(除了在tomcat中禁用安全管理器之外)是向我的策略文件添加开放式权限:

    grant {
      permission java.security.AllPermission;
    };
    

    我认为这在功能上等同于关闭安全管理器。

    我想我必须在我的授权中明确错误地获得codeBase声明,但我现在还没有看到它。

4 个答案:

答案 0 :(得分:2)

您使用的是Ubuntu的软件包托管版本吗?我们最近遇到了一个带有安全问题的噩梦,但发现通过单独下载Tomcat并使用它,安全问题就消失了。

确证:

http://www.howtogeek.com/howto/linux/installing-tomcat-6-on-ubuntu/

  

如果您正在运行Ubuntu并且想要使用Tomcat servlet容器,则不应使用存储库中的版本,因为它无法正常工作。相反,您需要使用我在此概述的手动安装过程。

答案 1 :(得分:0)

Tomcat使用自己的tomcat用户运行。战争文件需要对该用户可见 - 可能值得先检查一下吗?

答案 2 :(得分:0)

您是否直接部署到ROOT目录?

通常当你在webapps文件夹中输入一个war,比如说100myapp.war时,它会解压缩到一个名为100myapp的文件夹中。那么不应该在这个新文件夹而不是ROOT文件夹上完成授权吗?

答案 3 :(得分:0)

您可能需要单独授予文件访问权限。尝试将应用的授权更改为:

grant codeBase "file:${catalina.base}/webapps/ROOT.war" {
  permission java.security.AllPermission;
  permission java.io.FilePermission "file:${catalina.base}/webapps/ROOT/-", "read, write";
}

如果这不起作用,那么可能是您现有授权所涵盖的代码之外的某些代码正在访问这些属性文件(例如servlet或其他库代码)。

作为一种解决方法,并确认是否属于这种情况,您可以对导致问题的.properties进行直接授权:

grant {
  permission java.io.FilePermission "file:${catalina.base}/webapps/ROOT/WEB-INF/classes/com/foo/some-file-here.txt", "read, write";
}

事实上,后者可能就是这种情况,因为堆栈跟踪显示了Tomcat的上下文加载器中的代码。如果.properties上的直接授权有效,您可能希望将授权锁定到org.apache.naming.resources.FileDirContext。

您是否获得了特定于您自己代码的堆栈跟踪?