Oct 6, 2018

Java: Slow java with server.policy enabled - how to fix this issue

If you use Java security manager for hardening your java processes, you have to add the following JVM options:
-Djava.security.manager
-Djava.security.policy=server.policy 
Create a server.policy file (you can use jdkXXX/jre/lib/security/java.policy as a tamplate) and add the following line:
permission java.net.SocketPermission "localhost:*", "listen, accept, connect, resolve"; 
Now create a small java program, which listens on a port (like this example).

If you send a message with netcat
nc -u localhost 9876
Everyhting is fine.
Now send a message from a remote host. This does not work - like expected.

Try it again with the following network tracing running (capturing all DNS packets):
tcpdump -i any port 53
Cool. For each connect a DNS-Lookup is done.
This could be a problem for high performance systems or for systems, which have to running/reachable DNS-Servers. In the latter case all requests will be sent to localhost:53 and of course, localhost will not give any answer. (This is not true - there will be a "ICMP - not reachable", but no DNS answer.).
If you add now line with *.*, to allow the connection the server.policy file should contain the following lines:
permission java.net.SocketPermission "*:*", "listen, accept, connect, resolve";
permission java.net.SocketPermission "localhost:*", "listen, accept, connect, resolve"; 
Hmmm. The connection is allowed, but there still DNS requests happening. The problem is that "*:*" is behind the "localhost:*" because Java reads this file from bottom to top - so if you write it this way:
permission java.net.SocketPermission "localhost:*", "listen, accept, connect, resolve";
permission java.net.SocketPermission "*:*", "listen, accept, connect, resolve";
there are no DNS requests happening anymore.

If you still see DNS requests: Take a look at this file:
YourJDK/jre/lib/security/java.policy
there are some entries with java.net.SocketPermission like:
permission java.net.SocketPermission "localhost:0", "listen";
 Because java first checks this file, you have to remove such lines, to get rid of the DNS requests.

If you do not need to use DNS, you should remove dns in /etc/nsswitch.conf. But, then no domain lookup will succeed  on this machine anymore...

No comments:

Post a Comment