How to get Oracle java 7 to work with setcap cap_net_bind_service+ep
Solution 1
Until you asked the question I never even heard of this facility in Unix (file capabilities). I found this link which looks to have the solution as to how to make ld.so trust your shared libraries:
excerpt from that post
When one is raising the privileges of an executable, the runtime loader (rtld), better know as ld.so will not link with libraries in untrusted paths. This is the way the ld.so(1) has been designed. If one needs to run such an executable, then you have to add that path to the trusted paths of ld.so, the following describes how to do so:
Fedora 11: % uname -a Linux localhost.localdomain 2.6.29.4-167.fc11.i686.PAE #1 SMP Wed May 27 17:28:22 EDT 2009 i686 i686 i386 GNU/Linux % sudo setcap cap_net_raw+epi ./jdk1.7.0_04/bin/java % ./jdk1.7.0_04/bin/java -version ./jdk1.7.0_04/bin/java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory
Its kaput, Ok we are on the same page now, to fix this, create a file such as > this, with the path to libjli.so
% cat /etc/ld.so.conf.d/java.conf /home/someuser/jdk1.7.0_04/jre/lib/i386/jli
This will add the the pathname to the trusted user path, that ld.so will use, to build its runtime cache, verify if ld.so is seeing it by doing this, need to run it as root, and a reboot may be necessary.
% ldconfig | grep libjli libjli.so -> libjli.so .......
Now test java:
% ./jdk1.7.0_04/bin/java -version java version "1.7.0_04-ea" Java(TM) SE Runtime Environment (build 1.7.0_04-ea-b18)
and there you have it.....
References
- POSIX file capabilities: Parceling the power of root
- This is the Linux kernel capabilities FAQ
- capabilities man page
- Capability-based security - wikipedia
- Using File Capabilities Instead Of Setuid
Solution 2
Just to show the full process to enable Java listenign at port 80 (or any port below 1024):
- For a JAVA_HOME:
$> export JAVA_HOME=/usr/local/java/graalvm-ce-java8-20.2.0
- You should enable the capability to the java binary:
$> sudo /sbin/setcap 'cap_net_bind_service=ep' /usr/local/java/graalvm-ce-java8-20.2.0/bin/java
- After that you will start to get some error when running java:
$> java -version ./bin/java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory
- To fix that you should update
ldconfig
. Just create ajava.conf
file:$> cat /etc/ld.so.conf.d/java.conf /usr/local/java/graalvm-ce-java8-20.2.0/lib/amd64/jli /usr/local/java/graalvm-ce-java8-20.2.0/jre/lib/amd64/jli $> java -version
- Now java works:
$> java -version openjdk version "1.8.0_262" ...
Related videos on Youtube
Comments
-
ams over 1 year
I am trying to grant the java executable the right to open ports below 1024 on Linux. Here is the setup
-
/home/test/java
contains the Oracle Server JRE 7.0.25 - CentOS 6.4
Here is what getcap returns
[test@centos6 java]$ pwd /home/test/java [test@centos6 java]$ getcap bin/java bin/java = cap_net_bind_service+ep [test@centos6 java]$ getcap jre/bin/java jre/bin/java = cap_net_bind_service+ep
Trying to execute java gives the following error.
[test@centos6 java]$ bin/java bin/java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory [test@centos6 java]$ jre/bin/java jre/bin/java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory
Is it possible to run Java 7_u25 when the binary has been given elevated privileges with setcap, if so how?
JDK-6919633 : Runtime does not support POSIX File Capabilities (A.K.A. Linux Capabilities) says that
Note: when using the setcap the libraries needed by the java launcher should be present in /usr/lib or any other "trusted" location that the runtime loader (rtld) uses to find shared libraries.
How do I make the shared libraries trusted?
-
-
ams almost 11 yearsThis approach seems to be a system wide change, is there way to restrict the trust on a per user basis so that user foo and bar can have their own different versions of java with different version of libjli.so without running into conflict.