How to get Oracle java 7 to work with setcap cap_net_bind_service+ep

16,381

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

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 a java.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"
    ...
    
Share:
16,381

Related videos on Youtube

ams
Author by

ams

I love software development.

Updated on September 18, 2022

Comments

  • ams
    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
    ams almost 11 years
    This 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.