如何在 Tomcat 6 中合理配置安全策略
我使用的是为 Ubuntu Karmic 打包的 Tomcat 6.0.24。 Ubuntu 的 Tomcat 软件包的默认安全策略相当严格,但看起来很简单。在/var/lib/tomcat6/conf/policy.d
中,有各种建立默认策略的文件。
一开始值得注意的是:
- 我根本没有更改库存 tomcat 安装 - 没有新的 jar 到其公共 lib 目录中,没有
server.xml
更改等。webapps
目录中的文件是唯一的部署操作。 - 我正在部署的 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)
我非常确信触发拒绝的实际文件是无关紧要的——它只是我们检查可选配置参数的一些属性文件。有趣的是:
- 在这个上下文中它不存在,
- 文件不存在的事实最终会引发安全异常,而不是
java.io.File.exists()
简单地返回 false (尽管我认为这只是读取权限的语义问题)。
另一种解决方法(除了禁用 tomcat 中的安全管理器之外)是向我的策略文件添加开放式权限:
grant {
permission java.security.AllPermission;
};
我认为这在功能上相当于关闭安全管理器。
我想我的赠款中的 codeBase
声明一定是错误的,但我现在没有看到它。
I'm using Tomcat 6.0.24, as packaged for Ubuntu Karmic. The default security policy of Ubuntu's Tomcat package is pretty stringent, but appears straightforward. In /var/lib/tomcat6/conf/policy.d
, there are a variety of files that establish default policy.
Worth noting at the start:
- I've not changed the stock tomcat install at all -- no new jars into its common lib directory(ies), no
server.xml
changes, etc. Putting the .war file in thewebapps
directory is the only deployment action. - the web application I'm deploying fails with thousands of access denials under this default policy (as reported to the log thanks to the
-Djava.security.debug="access,stack,failure"
system property). - turning off the security manager entirely results in no errors whatsoever, and proper app functionality
What I'd like to do is add an application-specific security policy file to the policy.d
directory, which seems to be the recommended practice. I added this to policy.d/100myapp.policy
(as a starting point -- I would like to eventually trim back the granted permissions to only what the app actually needs):
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;
};
Note the thrashing around attempting to find the right codeBase
declaration. I think that's likely my fundamental problem.
Anyway, the above (really only the first two grants appear to have any effect) almost works: the thousands of access denials are gone, and I'm left with just one. Relevant stack trace:
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)
I'm pretty convinced that the actual file that's triggering the denial is irrelevant -- it's just some properties file that we check for optional configuration parameters. What's interesting is that:
- it doesn't exist in this context
- the fact that the file doesn't exist ends up throwing a security exception, rather than
java.io.File.exists()
simply returning false (although I suppose that's just a matter of the semantics of the read permission).
Another workaround (besides just disabling the security manager in tomcat) is to add an open-ended permission to my policy file:
grant {
permission java.security.AllPermission;
};
I presume this is functionally equivalent to turning off the security manager.
I suppose I must be getting the codeBase
declaration in my grants subtly wrong, but I'm not seeing it at the moment.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您使用的是 Ubuntu 的包管理版本吗?最近我们对它的安全问题做了一场噩梦,但发现通过单独下载 Tomcat 并使用它,安全问题就消失了。
佐证:
http://www.howtogeek.com/howto /linux/安装-tomcat-6-on-ubuntu/
Are you using Ubuntu's package-managed version? We had a nightmare recently with security stuff with it, but found that by downloading Tomcat separately and using that, the security issues went away.
Corroboration:
http://www.howtogeek.com/howto/linux/installing-tomcat-6-on-ubuntu/
Tomcat 使用自己的 tomcat 用户运行。战争文件需要对该用户可见 - 可能值得首先检查?
Tomcat runs with its own tomcat user. The war files need to be visible to that user - probably worth checking that first?
是直接部署到ROOT目录吗?
通常,当您将 war 放入 webapps 文件夹(例如
100myapp.war
)时,它会解压到名为100myapp
的文件夹中。难道不应该在这个新文件夹而不是 ROOT 文件夹上完成授权吗?Are you directly deploying to the ROOT directory ?
Usually when you put a war in the webapps folder, say
100myapp.war
, it unpacks to a folder named100myapp
itself. Shouldn't the grants then be done on this new folder rather than the ROOT folder ?您可能必须单独授予文件访问权限。尝试将您的应用程序的授权更改为:
如果这不起作用,则可能是现有授权范围之外的某些代码正在访问这些属性文件(例如 servlet 或其他库代码)。
作为解决方法,并确认是否是这种情况,您可以对导致问题的 .properties 进行直接授予:
事实上,似乎后者可能是这种情况,因为堆栈跟踪显示 Tomcat 上下文中的代码装载机。如果 .properties 上的直接授权有效,您可能希望将授权锁定到 org.apache.naming.resources.FileDirContext。
您是否获得了特定于您自己的代码的堆栈跟踪?
It's possible that you have to grant file access permissions separately. Try changing the grant for your app to:
If that doesn't work, then it could be that some code outside of what your existing grants cover is accessing those property files (e.g. servlet or other library code).
As a workaround, and to confirm if this is the case, you could do a straight grant on the .properties that are causing you the problem:
It seems in fact that the latter could be the case since the stack trace shows code in Tomcat's context loader. If the straight grant on the .properties works, you might want to lock the grant down to org.apache.naming.resources.FileDirContext.
Do you get any stack traces specific to your own code?